diff --git a/doc/src/JPG/gran_funnel.png b/doc/src/JPG/gran_funnel.png new file mode 100644 index 000000000..8e26005f7 Binary files /dev/null and b/doc/src/JPG/gran_funnel.png differ diff --git a/doc/src/JPG/gran_funnel_small.jpg b/doc/src/JPG/gran_funnel_small.jpg new file mode 100644 index 000000000..6e2980338 Binary files /dev/null and b/doc/src/JPG/gran_funnel_small.jpg differ diff --git a/doc/src/JPG/gran_mixer.png b/doc/src/JPG/gran_mixer.png new file mode 100644 index 000000000..6ea722124 Binary files /dev/null and b/doc/src/JPG/gran_mixer.png differ diff --git a/doc/src/JPG/gran_mixer_small.jpg b/doc/src/JPG/gran_mixer_small.jpg new file mode 100644 index 000000000..7cc85d92b Binary files /dev/null and b/doc/src/JPG/gran_mixer_small.jpg differ diff --git a/doc/src/Manual.txt b/doc/src/Manual.txt index 10487375f..21cc9bccc 100644 --- a/doc/src/Manual.txt +++ b/doc/src/Manual.txt @@ -1,340 +1,340 @@ LAMMPS Users Manual - + "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

LAMMPS Documentation :c,h3 -5 Oct 2016 version :c,h4 +6 Oct 2016 version :c,h4 Version info: :h4 The LAMMPS "version" is the date when it was released, such as 1 May 2010. LAMMPS is updated continuously. Whenever we fix a bug or add a feature, we release it immediately, and post a notice on "this page of the WWW site"_bug. Every 2-4 months one of the incremental releases is subjected to more thorough testing and labeled as a {stable} version. Each dated copy of LAMMPS contains all the features and bug-fixes up to and including that version date. The version date is printed to the screen and logfile every time you run LAMMPS. It is also in the file src/version.h and in the LAMMPS directory name created when you unpack a tarball, and at the top of the first page of the manual (this page). If you browse the HTML doc pages on the LAMMPS WWW site, they always describe the most current version of LAMMPS. :ulb,l If you browse the HTML doc pages included in your tarball, they describe the version you have. :l The "PDF file"_Manual.pdf on the WWW site or in the tarball is updated about once per month. This is because it is large, and we don't want it to be part of every patch. :l There is also a "Developer.pdf"_Developer.pdf file in the doc directory, which describes the internal structure and algorithms of LAMMPS. :l :ule LAMMPS stands for Large-scale Atomic/Molecular Massively Parallel Simulator. LAMMPS is a classical molecular dynamics simulation code designed to run efficiently on parallel computers. It was developed at Sandia National Laboratories, a US Department of Energy facility, with funding from the DOE. It is an open-source code, distributed freely under the terms of the GNU Public License (GPL). The current core group of LAMMPS developers is at Sandia National Labs and Temple University: "Steve Plimpton"_sjp, sjplimp at sandia.gov :ulb,l Aidan Thompson, athomps at sandia.gov :l Stan Moore, stamoore at sandia.gov :l "Axel Kohlmeyer"_ako, akohlmey at gmail.com :l :ule Past core developers include Paul Crozier, Ray Shan and Mark Stevens, all at Sandia. The [LAMMPS home page] at "http://lammps.sandia.gov"_http://lammps.sandia.gov has more information about the code and its uses. Interaction with external LAMMPS developers, bug reports and feature requests are mainly coordinated through the "LAMMPS project on GitHub."_https://github.com/lammps/lammps The lammps.org domain, currently hosting "public continuous integration testing"_https://ci.lammps.org/job/lammps/ and "precompiled Linux RPM and Windows installer packages"_http://rpm.lammps.org is located at Temple University and managed by Richard Berger, richard.berger at temple.edu. :link(bug,http://lammps.sandia.gov/bug.html) :link(sjp,http://www.sandia.gov/~sjplimp) :link(ako,http://goo.gl/1wk0) :line The LAMMPS documentation is organized into the following sections. If you find errors or omissions in this manual or have suggestions for useful information to add, please send an email to the developers so we can improve the LAMMPS documentation. Once you are familiar with LAMMPS, you may want to bookmark "this page"_Section_commands.html#comm at Section_commands.html#comm since it gives quick access to documentation for all LAMMPS commands. "PDF file"_Manual.pdf of the entire manual, generated by "htmldoc"_http://freecode.com/projects/htmldoc "Introduction"_Section_intro.html :olb,l 1.1 "What is LAMMPS"_intro_1 :ulb,b 1.2 "LAMMPS features"_intro_2 :b 1.3 "LAMMPS non-features"_intro_3 :b 1.4 "Open source distribution"_intro_4 :b 1.5 "Acknowledgments and citations"_intro_5 :ule,b "Getting started"_Section_start.html :l 2.1 "What's in the LAMMPS distribution"_start_1 :ulb,b 2.2 "Making LAMMPS"_start_2 :b 2.3 "Making LAMMPS with optional packages"_start_3 :b 2.4 "Building LAMMPS via the Make.py script"_start_4 :b 2.5 "Building LAMMPS as a library"_start_5 :b 2.6 "Running LAMMPS"_start_6 :b 2.7 "Command-line options"_start_7 :b 2.8 "Screen output"_start_8 :b 2.9 "Tips for users of previous versions"_start_9 :ule,b "Commands"_Section_commands.html :l 3.1 "LAMMPS input script"_cmd_1 :ulb,b 3.2 "Parsing rules"_cmd_2 :b 3.3 "Input script structure"_cmd_3 :b 3.4 "Commands listed by category"_cmd_4 :b 3.5 "Commands listed alphabetically"_cmd_5 :ule,b "Packages"_Section_packages.html :l 4.1 "Standard packages"_pkg_1 :ulb,b 4.2 "User packages"_pkg_2 :ule,b "Accelerating LAMMPS performance"_Section_accelerate.html :l 5.1 "Measuring performance"_acc_1 :ulb,b 5.2 "Algorithms and code options to boost performace"_acc_2 :b 5.3 "Accelerator packages with optimized styles"_acc_3 :b 5.3.1 "GPU package"_accelerate_gpu.html :ulb,b 5.3.2 "USER-INTEL package"_accelerate_intel.html :b 5.3.3 "KOKKOS package"_accelerate_kokkos.html :b 5.3.4 "USER-OMP package"_accelerate_omp.html :b 5.3.5 "OPT package"_accelerate_opt.html :ule,b 5.4 "Comparison of various accelerator packages"_acc_4 :ule,b "How-to discussions"_Section_howto.html :l 6.1 "Restarting a simulation"_howto_1 :ulb,b 6.2 "2d simulations"_howto_2 :b 6.3 "CHARMM and AMBER force fields"_howto_3 :b 6.4 "Running multiple simulations from one input script"_howto_4 :b 6.5 "Multi-replica simulations"_howto_5 :b 6.6 "Granular models"_howto_6 :b 6.7 "TIP3P water model"_howto_7 :b 6.8 "TIP4P water model"_howto_8 :b 6.9 "SPC water model"_howto_9 :b 6.10 "Coupling LAMMPS to other codes"_howto_10 :b 6.11 "Visualizing LAMMPS snapshots"_howto_11 :b 6.12 "Triclinic (non-orthogonal) simulation boxes"_howto_12 :b 6.13 "NEMD simulations"_howto_13 :b 6.14 "Finite-size spherical and aspherical particles"_howto_14 :b 6.15 "Output from LAMMPS (thermo, dumps, computes, fixes, variables)"_howto_15 :b 6.16 "Thermostatting, barostatting, and compute temperature"_howto_16 :b 6.17 "Walls"_howto_17 :b 6.18 "Elastic constants"_howto_18 :b 6.19 "Library interface to LAMMPS"_howto_19 :b 6.20 "Calculating thermal conductivity"_howto_20 :b 6.21 "Calculating viscosity"_howto_21 :b 6.22 "Calculating a diffusion coefficient"_howto_22 :b 6.23 "Using chunks to calculate system properties"_howto_23 :b 6.24 "Setting parameters for pppm/disp"_howto_24 :b 6.25 "Polarizable models"_howto_25 :b 6.26 "Adiabatic core/shell model"_howto_26 :b 6.27 "Drude induced dipoles"_howto_27 :ule,b "Example problems"_Section_example.html :l "Performance & scalability"_Section_perf.html :l "Additional tools"_Section_tools.html :l "Modifying & extending LAMMPS"_Section_modify.html :l 10.1 "Atom styles"_mod_1 :ulb,b 10.2 "Bond, angle, dihedral, improper potentials"_mod_2 :b 10.3 "Compute styles"_mod_3 :b 10.4 "Dump styles"_mod_4 :b 10.5 "Dump custom output options"_mod_5 :b 10.6 "Fix styles"_mod_6 :b 10.7 "Input script commands"_mod_7 :b 10.8 "Kspace computations"_mod_8 :b 10.9 "Minimization styles"_mod_9 :b 10.10 "Pairwise potentials"_mod_10 :b 10.11 "Region styles"_mod_11 :b 10.12 "Body styles"_mod_12 :b 10.13 "Thermodynamic output options"_mod_13 :b 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 "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 12.3 "Error & warning messages"_err_3 :ule,b "Future and history"_Section_history.html :l 13.1 "Coming attractions"_hist_1 :ulb,b 13.2 "Past versions"_hist_2 :ule,b :ole :link(intro_1,Section_intro.html#intro_1) :link(intro_2,Section_intro.html#intro_2) :link(intro_3,Section_intro.html#intro_3) :link(intro_4,Section_intro.html#intro_4) :link(intro_5,Section_intro.html#intro_5) :link(start_1,Section_start.html#start_1) :link(start_2,Section_start.html#start_2) :link(start_3,Section_start.html#start_3) :link(start_4,Section_start.html#start_4) :link(start_5,Section_start.html#start_5) :link(start_6,Section_start.html#start_6) :link(start_7,Section_start.html#start_7) :link(start_8,Section_start.html#start_8) :link(start_9,Section_start.html#start_9) :link(cmd_1,Section_commands.html#cmd_1) :link(cmd_2,Section_commands.html#cmd_2) :link(cmd_3,Section_commands.html#cmd_3) :link(cmd_4,Section_commands.html#cmd_4) :link(cmd_5,Section_commands.html#cmd_5) :link(pkg_1,Section_packages.html#pkg_1) :link(pkg_2,Section_packages.html#pkg_2) :link(acc_1,Section_accelerate.html#acc_1) :link(acc_2,Section_accelerate.html#acc_2) :link(acc_3,Section_accelerate.html#acc_3) :link(acc_4,Section_accelerate.html#acc_4) :link(howto_1,Section_howto.html#howto_1) :link(howto_2,Section_howto.html#howto_2) :link(howto_3,Section_howto.html#howto_3) :link(howto_4,Section_howto.html#howto_4) :link(howto_5,Section_howto.html#howto_5) :link(howto_6,Section_howto.html#howto_6) :link(howto_7,Section_howto.html#howto_7) :link(howto_8,Section_howto.html#howto_8) :link(howto_9,Section_howto.html#howto_9) :link(howto_10,Section_howto.html#howto_10) :link(howto_11,Section_howto.html#howto_11) :link(howto_12,Section_howto.html#howto_12) :link(howto_13,Section_howto.html#howto_13) :link(howto_14,Section_howto.html#howto_14) :link(howto_15,Section_howto.html#howto_15) :link(howto_16,Section_howto.html#howto_16) :link(howto_17,Section_howto.html#howto_17) :link(howto_18,Section_howto.html#howto_18) :link(howto_19,Section_howto.html#howto_19) :link(howto_20,Section_howto.html#howto_20) :link(howto_21,Section_howto.html#howto_21) :link(howto_22,Section_howto.html#howto_22) :link(howto_23,Section_howto.html#howto_23) :link(howto_24,Section_howto.html#howto_24) :link(howto_25,Section_howto.html#howto_25) :link(howto_26,Section_howto.html#howto_26) :link(howto_27,Section_howto.html#howto_27) :link(mod_1,Section_modify.html#mod_1) :link(mod_2,Section_modify.html#mod_2) :link(mod_3,Section_modify.html#mod_3) :link(mod_4,Section_modify.html#mod_4) :link(mod_5,Section_modify.html#mod_5) :link(mod_6,Section_modify.html#mod_6) :link(mod_7,Section_modify.html#mod_7) :link(mod_8,Section_modify.html#mod_8) :link(mod_9,Section_modify.html#mod_9) :link(mod_10,Section_modify.html#mod_10) :link(mod_11,Section_modify.html#mod_11) :link(mod_12,Section_modify.html#mod_12) :link(mod_13,Section_modify.html#mod_13) :link(mod_14,Section_modify.html#mod_14) :link(mod_15,Section_modify.html#mod_15) :link(py_1,Section_python.html#py_1) :link(py_2,Section_python.html#py_2) :link(py_3,Section_python.html#py_3) :link(py_4,Section_python.html#py_4) :link(py_5,Section_python.html#py_5) :link(py_6,Section_python.html#py_6) :link(err_1,Section_errors.html#err_1) :link(err_2,Section_errors.html#err_2) :link(err_3,Section_errors.html#err_3) :link(hist_1,Section_history.html#hist_1) :link(hist_2,Section_history.html#hist_2) diff --git a/doc/src/Section_commands.txt b/doc/src/Section_commands.txt index 3a6de833f..2eef5d1d2 100644 --- a/doc/src/Section_commands.txt +++ b/doc/src/Section_commands.txt @@ -1,1135 +1,1136 @@ "Previous Section"_Section_start.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next Section"_Section_packages.html :c :link(lws,http://lammps.sandia.gov) :link(ld,Manual.html) :link(lc,Section_commands.html#comm) :line 3. Commands :h3 This section describes how a LAMMPS input script is formatted and the input script commands used to define a LAMMPS simulation. 3.1 "LAMMPS input script"_#cmd_1 3.2 "Parsing rules"_#cmd_2 3.3 "Input script structure"_#cmd_3 3.4 "Commands listed by category"_#cmd_4 3.5 "Commands listed alphabetically"_#cmd_5 :all(b) :line :line 3.1 LAMMPS input script :link(cmd_1),h4 LAMMPS executes by reading commands from a input script (text file), one line at a time. When the input script ends, LAMMPS exits. Each command causes LAMMPS to take some action. It may set an internal variable, read in a file, or run a simulation. Most commands have default settings, which means you only need to use the command if you wish to change the default. In many cases, the ordering of commands in an input script is not important. However the following rules apply: (1) LAMMPS does not read your entire input script and then perform a simulation with all the settings. Rather, the input script is read one line at a time and each command takes effect when it is read. Thus this sequence of commands: timestep 0.5 run 100 run 100 :pre does something different than this sequence: run 100 timestep 0.5 run 100 :pre In the first case, the specified timestep (0.5 fmsec) is used for two simulations of 100 timesteps each. In the 2nd case, the default timestep (1.0 fmsec) is used for the 1st 100 step simulation and a 0.5 fmsec timestep is used for the 2nd one. (2) Some commands are only valid when they follow other commands. For example you cannot set the temperature of a group of atoms until atoms have been defined and a group command is used to define which atoms belong to the group. (3) Sometimes command B will use values that can be set by command A. This means command A must precede command B in the input script if it is to have the desired effect. For example, the "read_data"_read_data.html command initializes the system by setting up the simulation box and assigning atoms to processors. If default values are not desired, the "processors"_processors.html and "boundary"_boundary.html commands need to be used before read_data to tell LAMMPS how to map processors to the simulation box. Many input script errors are detected by LAMMPS and an ERROR or WARNING message is printed. "This section"_Section_errors.html gives more information on what errors mean. The documentation for each command lists restrictions on how the command can be used. :line 3.2 Parsing rules :link(cmd_2),h4 Each non-blank line in the input script is treated as a command. LAMMPS commands are case sensitive. Command names are lower-case, as are specified command arguments. Upper case letters may be used in 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, 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 comment after a trailing "&" character will prevent the command from continuing on the next line. Also note that for multi-line commands a single leading "#" will comment out the entire command. (3) The line is searched repeatedly for $ characters, which indicate variables that are replaced with a text string. See an exception in (6). If the $ is followed by curly brackets, then the variable name is the text inside the curly brackets. If no curly brackets follow the $, then the variable name is the single character immediately following the $. Thus $\{myTemp\} and $x refer to variable names "myTemp" and "x". How the variable is converted to a text string depends on what style of variable it is; see the "variable"_variable doc page for details. It can be a variable that stores multiple text strings, and return one of them. The returned text string can be multiple "words" (space separated) which will then be interpreted as multiple arguments in the input command. The variable can also store a numeric formula which will be evaluated and its numeric result returned as a string. As a special case, if the $ is followed by parenthesis, then the text inside the parenthesis is treated as an "immediate" variable and evaluated as an "equal-style variable"_variable.html. This is a way to use numeric formulas in an input script without having to assign them to variable names. For example, these 3 input script lines: variable X equal (xlo+xhi)/2+sqrt(v_area) region 1 block $X 2 INF INF EDGE EDGE variable X delete :pre can be replaced by region 1 block $((xlo+xhi)/2+sqrt(v_area)) 2 INF INF EDGE EDGE :pre so that you do not have to define (or discard) a temporary variable X. Note that neither the curly-bracket or immediate form of variables can contain nested $ characters for other variables to substitute for. Thus you cannot do this: variable a equal 2 variable b2 equal 4 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 "equal-style variable"_variable.html. See the "variable"_variable.html command for more details of how strings are assigned to variables and evaluated, and how they can be used in input script commands. (4) The line is broken into "words" separated by whitespace (tabs, spaces). Note that words can thus contain letters, digits, underscores, or punctuation characters. (5) The first word is the command name. All successive words in the line are arguments. (6) If you want text with spaces to be treated as a single argument, 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" print """ System volume = $v System temperature = $t """ :pre 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, "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). 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 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. :line 3.3 Input script structure :h4,link(cmd_3) This section describes the structure of a typical LAMMPS input script. The "examples" directory in the LAMMPS distribution contains many sample input scripts; the corresponding problems are discussed in "Section 7"_Section_example.html, and animated on the "LAMMPS WWW Site"_lws. A LAMMPS input script typically has 4 parts: Initialization Atom definition Settings Run a simulation :ol The last 2 parts can be repeated as many times as desired. I.e. run a simulation, change some settings, run some more, etc. Each of the 4 parts is now described in more detail. Remember that almost all the commands need only be used if a non-default value is desired. (1) Initialization Set parameters that need to be defined before atoms are created or read-in from a file. The relevant commands are "units"_units.html, "dimension"_dimension.html, "newton"_newton.html, "processors"_processors.html, "boundary"_boundary.html, "atom_style"_atom_style.html, "atom_modify"_atom_modify.html. If force-field parameters appear in the files that will be read, these commands tell LAMMPS what kinds of force fields are being used: "pair_style"_pair_style.html, "bond_style"_bond_style.html, "angle_style"_angle_style.html, "dihedral_style"_dihedral_style.html, "improper_style"_improper_style.html. (2) Atom definition There are 3 ways to define atoms in LAMMPS. Read them in from a data or restart file via the "read_data"_read_data.html or "read_restart"_read_restart.html commands. These files can contain molecular topology information. Or create atoms on a lattice (with no molecular topology), using these commands: "lattice"_lattice.html, "region"_region.html, "create_box"_create_box.html, "create_atoms"_create_atoms.html. The entire set of atoms can be duplicated to make a larger simulation using the "replicate"_replicate.html command. (3) Settings Once atoms and molecular topology are defined, a variety of settings can be specified: force field coefficients, simulation parameters, output options, etc. Force field coefficients are set by these commands (they can also be set in the read-in files): "pair_coeff"_pair_coeff.html, "bond_coeff"_bond_coeff.html, "angle_coeff"_angle_coeff.html, "dihedral_coeff"_dihedral_coeff.html, "improper_coeff"_improper_coeff.html, "kspace_style"_kspace_style.html, "dielectric"_dielectric.html, "special_bonds"_special_bonds.html. Various simulation parameters are set by these commands: "neighbor"_neighbor.html, "neigh_modify"_neigh_modify.html, "group"_group.html, "timestep"_timestep.html, "reset_timestep"_reset_timestep.html, "run_style"_run_style.html, "min_style"_min_style.html, "min_modify"_min_modify.html. Fixes impose a variety of boundary conditions, time integration, and diagnostic options. The "fix"_fix.html command comes in many flavors. Various computations can be specified for execution during a simulation using the "compute"_compute.html, "compute_modify"_compute_modify.html, and "variable"_variable.html commands. Output options are set by the "thermo"_thermo.html, "dump"_dump.html, and "restart"_restart.html commands. (4) Run a simulation A molecular dynamics simulation is run using the "run"_run.html command. Energy minimization (molecular statics) is performed using the "minimize"_minimize.html command. A parallel tempering (replica-exchange) simulation can be run using the "temper"_temper.html command. :line 3.4 Commands listed by category :link(cmd_4),h4 This section lists all LAMMPS commands, grouped by category. The "next section"_#cmd_5 lists the same commands alphabetically. Note that some style options for some commands are part of specific LAMMPS packages, which means they cannot be used unless the package was included when LAMMPS was built. Not all packages are included in a default LAMMPS build. These dependencies are listed as Restrictions in the command's documentation. Initialization: "atom_modify"_atom_modify.html, "atom_style"_atom_style.html, "boundary"_boundary.html, "dimension"_dimension.html, "newton"_newton.html, "processors"_processors.html, "units"_units.html Atom definition: "create_atoms"_create_atoms.html, "create_box"_create_box.html, "lattice"_lattice.html, "read_data"_read_data.html, "read_dump"_read_dump.html, "read_restart"_read_restart.html, "region"_region.html, "replicate"_replicate.html Force fields: "angle_coeff"_angle_coeff.html, "angle_style"_angle_style.html, "bond_coeff"_bond_coeff.html, "bond_style"_bond_style.html, "dielectric"_dielectric.html, "dihedral_coeff"_dihedral_coeff.html, "dihedral_style"_dihedral_style.html, "improper_coeff"_improper_coeff.html, "improper_style"_improper_style.html, "kspace_modify"_kspace_modify.html, "kspace_style"_kspace_style.html, "pair_coeff"_pair_coeff.html, "pair_modify"_pair_modify.html, "pair_style"_pair_style.html, "pair_write"_pair_write.html, "special_bonds"_special_bonds.html Settings: "comm_style"_comm_style.html, "group"_group.html, "mass"_mass.html, "min_modify"_min_modify.html, "min_style"_min_style.html, "neigh_modify"_neigh_modify.html, "neighbor"_neighbor.html, "reset_timestep"_reset_timestep.html, "run_style"_run_style.html, "set"_set.html, "timestep"_timestep.html, "velocity"_velocity.html Fixes: "fix"_fix.html, "fix_modify"_fix_modify.html, "unfix"_unfix.html Computes: "compute"_compute.html, "compute_modify"_compute_modify.html, "uncompute"_uncompute.html Output: "dump"_dump.html, "dump image"_dump_image.html, "dump_modify"_dump_modify.html, "dump movie"_dump_image.html, "restart"_restart.html, "thermo"_thermo.html, "thermo_modify"_thermo_modify.html, "thermo_style"_thermo_style.html, "undump"_undump.html, "write_data"_write_data.html, "write_dump"_write_dump.html, "write_restart"_write_restart.html Actions: "delete_atoms"_delete_atoms.html, "delete_bonds"_delete_bonds.html, "displace_atoms"_displace_atoms.html, "change_box"_change_box.html, "minimize"_minimize.html, "neb"_neb.html "prd"_prd.html, "rerun"_rerun.html, "run"_run.html, "temper"_temper.html Miscellaneous: "clear"_clear.html, "echo"_echo.html, "if"_if.html, "include"_include.html, "jump"_jump.html, "label"_label.html, "log"_log.html, "next"_next.html, "print"_print.html, "shell"_shell.html, "variable"_variable.html :line 3.5 Individual commands :h4,link(cmd_5),link(comm) This section lists all LAMMPS commands alphabetically, with a separate listing below of styles within certain commands. The "previous section"_#cmd_4 lists the same commands, grouped by category. Note that some style options for some commands are part of specific LAMMPS packages, which means they cannot be used unless the package was included when LAMMPS was built. Not all packages are included in a default LAMMPS build. These dependencies are listed as Restrictions in the command's documentation. "angle_coeff"_angle_coeff.html, "angle_style"_angle_style.html, "atom_modify"_atom_modify.html, "atom_style"_atom_style.html, "balance"_balance.html, "bond_coeff"_bond_coeff.html, "bond_style"_bond_style.html, "bond_write"_bond_write.html, "boundary"_boundary.html, "box"_box.html, "change_box"_change_box.html, "clear"_clear.html, "comm_modify"_comm_modify.html, "comm_style"_comm_style.html, "compute"_compute.html, "compute_modify"_compute_modify.html, "create_atoms"_create_atoms.html, "create_bonds"_create_bonds.html, "create_box"_create_box.html, "delete_atoms"_delete_atoms.html, "delete_bonds"_delete_bonds.html, "dielectric"_dielectric.html, "dihedral_coeff"_dihedral_coeff.html, "dihedral_style"_dihedral_style.html, "dimension"_dimension.html, "displace_atoms"_displace_atoms.html, "dump"_dump.html, "dump image"_dump_image.html, "dump_modify"_dump_modify.html, "dump movie"_dump_image.html, "echo"_echo.html, "fix"_fix.html, "fix_modify"_fix_modify.html, "group"_group.html, "if"_if.html, "info"_info.html, "improper_coeff"_improper_coeff.html, "improper_style"_improper_style.html, "include"_include.html, "jump"_jump.html, "kspace_modify"_kspace_modify.html, "kspace_style"_kspace_style.html, "label"_label.html, "lattice"_lattice.html, "log"_log.html, "mass"_mass.html, "minimize"_minimize.html, "min_modify"_min_modify.html, "min_style"_min_style.html, "molecule"_molecule.html, "neb"_neb.html, "neigh_modify"_neigh_modify.html, "neighbor"_neighbor.html, "newton"_newton.html, "next"_next.html, "package"_package.html, "pair_coeff"_pair_coeff.html, "pair_modify"_pair_modify.html, "pair_style"_pair_style.html, "pair_write"_pair_write.html, "partition"_partition.html, "prd"_prd.html, "print"_print.html, "processors"_processors.html, "python"_python.html, "quit"_quit.html, "read_data"_read_data.html, "read_dump"_read_dump.html, "read_restart"_read_restart.html, "region"_region.html, "replicate"_replicate.html, "rerun"_rerun.html, "reset_timestep"_reset_timestep.html, "restart"_restart.html, "run"_run.html, "run_style"_run_style.html, "set"_set.html, "shell"_shell.html, "special_bonds"_special_bonds.html, "suffix"_suffix.html, "tad"_tad.html, "temper"_temper.html, "thermo"_thermo.html, "thermo_modify"_thermo_modify.html, "thermo_style"_thermo_style.html, "timer"_timer.html, "timestep"_timestep.html, "uncompute"_uncompute.html, "undump"_undump.html, "unfix"_unfix.html, "units"_units.html, "variable"_variable.html, "velocity"_velocity.html, "write_coeff"_write_coeff.html, "write_data"_write_data.html, "write_dump"_write_dump.html, "write_restart"_write_restart.html :tb(c=6,ea=c) These are additional commands in USER packages, which can be used if "LAMMPS is built with the appropriate package"_Section_start.html#start_3. "dump custom/vtk"_dump_custom_vtk.html, "group2ndx"_group2ndx.html, "ndx2group"_group2ndx.html :tb(c=3,ea=c) :line Fix styles :h4 See the "fix"_fix.html command for one-line descriptions of each style or click on the style itself for a full description. Some of the styles have accelerated versions, which can be used if LAMMPS is built with the "appropriate accelerated package"_Section_accelerate.html. This is indicated by additional letters in parenthesis: g = GPU, i = USER-INTEL, k = KOKKOS, o = USER-OMP, t = OPT. "adapt"_fix_adapt.html, "addforce"_fix_addforce.html, "append/atoms"_fix_append_atoms.html, "atom/swap"_fix_atom_swap.html, "aveforce"_fix_aveforce.html, "ave/atom"_fix_ave_atom.html, "ave/chunk"_fix_ave_chunk.html, "ave/correlate"_fix_ave_correlate.html, "ave/histo"_fix_ave_histo.html, "ave/histo/weight"_fix_ave_histo.html, "ave/time"_fix_ave_time.html, "balance"_fix_balance.html, "bond/break"_fix_bond_break.html, "bond/create"_fix_bond_create.html, "bond/swap"_fix_bond_swap.html, "box/relax"_fix_box_relax.html, "cmap"_fix_cmap.html, "controller"_fix_controller.html, "deform (k)"_fix_deform.html, "deposit"_fix_deposit.html, "drag"_fix_drag.html, "dt/reset"_fix_dt_reset.html, "efield"_fix_efield.html, "ehex"_fix_ehex.html, "enforce2d"_fix_enforce2d.html, "evaporate"_fix_evaporate.html, "external"_fix_external.html, "freeze"_fix_freeze.html, "gcmc"_fix_gcmc.html, "gld"_fix_gld.html, "gravity (o)"_fix_gravity.html, "heat"_fix_heat.html, "indent"_fix_indent.html, "langevin (k)"_fix_langevin.html, "lineforce"_fix_lineforce.html, "momentum"_fix_momentum.html, "move"_fix_move.html, "msst"_fix_msst.html, "neb"_fix_neb.html, "nph (ko)"_fix_nh.html, "nphug (o)"_fix_nphug.html, "nph/asphere (o)"_fix_nph_asphere.html, "nph/body"_fix_nph_body.html, "nph/sphere (o)"_fix_nph_sphere.html, "npt (kio)"_fix_nh.html, "npt/asphere (o)"_fix_npt_asphere.html, "npt/body"_fix_npt_body.html, "npt/sphere (o)"_fix_npt_sphere.html, "nve (kio)"_fix_nve.html, "nve/asphere (i)"_fix_nve_asphere.html, "nve/asphere/noforce"_fix_nve_asphere_noforce.html, "nve/body"_fix_nve_body.html, "nve/limit"_fix_nve_limit.html, "nve/line"_fix_nve_line.html, "nve/noforce"_fix_nve_noforce.html, "nve/sphere (o)"_fix_nve_sphere.html, "nve/tri"_fix_nve_tri.html, "nvt (iko)"_fix_nh.html, "nvt/asphere (o)"_fix_nvt_asphere.html, "nvt/body"_fix_nvt_body.html, "nvt/sllod (io)"_fix_nvt_sllod.html, "nvt/sphere (o)"_fix_nvt_sphere.html, "oneway"_fix_oneway.html, "orient/bcc"_fix_orient.html, "orient/fcc"_fix_orient.html, "planeforce"_fix_planeforce.html, "poems"_fix_poems.html, "pour"_fix_pour.html, "press/berendsen"_fix_press_berendsen.html, "print"_fix_print.html, "property/atom"_fix_property_atom.html, "qeq/comb (o)"_fix_qeq_comb.html, "qeq/dynamic"_fix_qeq.html, "qeq/fire"_fix_qeq.html, "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, "rigid (o)"_fix_rigid.html, "rigid/nph (o)"_fix_rigid.html, "rigid/npt (o)"_fix_rigid.html, "rigid/nve (o)"_fix_rigid.html, "rigid/nvt (o)"_fix_rigid.html, "rigid/small (o)"_fix_rigid.html, "rigid/small/nph"_fix_rigid.html, "rigid/small/npt"_fix_rigid.html, "rigid/small/nve"_fix_rigid.html, "rigid/small/nvt"_fix_rigid.html, "setforce (k)"_fix_setforce.html, "shake"_fix_shake.html, "spring"_fix_spring.html, "spring/chunk"_fix_spring_chunk.html, "spring/rg"_fix_spring_rg.html, "spring/self"_fix_spring_self.html, "srd"_fix_srd.html, "store/force"_fix_store_force.html, "store/state"_fix_store_state.html, "temp/berendsen"_fix_temp_berendsen.html, "temp/csld"_fix_temp_csvr.html, "temp/csvr"_fix_temp_csvr.html, "temp/rescale"_fix_temp_rescale.html, "tfmc"_fix_tfmc.html, "thermal/conductivity"_fix_thermal_conductivity.html, "tmd"_fix_tmd.html, "ttm"_fix_ttm.html, "tune/kspace"_fix_tune_kspace.html, "vector"_fix_vector.html, "viscosity"_fix_viscosity.html, "viscous"_fix_viscous.html, "wall/colloid"_fix_wall.html, "wall/gran"_fix_wall_gran.html, +"wall/gran/region"_fix_wall_gran_region.html, "wall/harmonic"_fix_wall.html, "wall/lj1043"_fix_wall.html, "wall/lj126"_fix_wall.html, "wall/lj93"_fix_wall.html, "wall/piston"_fix_wall_piston.html, "wall/reflect (k)"_fix_wall_reflect.html, "wall/region"_fix_wall_region.html, "wall/srd"_fix_wall_srd.html :tb(c=8,ea=c) These are additional fix styles in USER packages, which can be used if "LAMMPS is built with the appropriate package"_Section_start.html#start_3. "adapt/fep"_fix_adapt_fep.html, "addtorque"_fix_addtorque.html, "atc"_fix_atc.html, "ave/correlate/long"_fix_ave_correlate_long.html, "colvars"_fix_colvars.html, "drude"_fix_drude.html, "drude/transform/direct"_fix_drude_transform.html, "drude/transform/reverse"_fix_drude_transform.html, "eos/cv"_fix_eos_cv.html, "eos/table"_fix_eos_table.html, "eos/table/rx"_fix_eos_table_rx.html, "flow/gauss"_fix_flow_gauss.html, "gle"_fix_gle.html, "imd"_fix_imd.html, "ipi"_fix_ipi.html, "langevin/drude"_fix_langevin_drude.html, "langevin/eff"_fix_langevin_eff.html, "lb/fluid"_fix_lb_fluid.html, "lb/momentum"_fix_lb_momentum.html, "lb/pc"_fix_lb_pc.html, "lb/rigid/pc/sphere"_fix_lb_rigid_pc_sphere.html, "lb/viscous"_fix_lb_viscous.html, "meso"_fix_meso.html, "manifoldforce"_fix_manifoldforce.html, "meso/stationary"_fix_meso_stationary.html, "nve/manifold/rattle"_fix_nve_manifold_rattle.html, "nvt/manifold/rattle"_fix_nvt_manifold_rattle.html, "nph/eff"_fix_nh_eff.html, "npt/eff"_fix_nh_eff.html, "nve/eff"_fix_nve_eff.html, "nvt/eff"_fix_nh_eff.html, "nvt/sllod/eff"_fix_nvt_sllod_eff.html, "phonon"_fix_phonon.html, "pimd"_fix_pimd.html, "qbmsst"_fix_qbmsst.html, "qeq/reax"_fix_qeq_reax.html, "qmmm"_fix_qmmm.html, "qtb"_fix_qtb.html, "reax/c/bonds"_fix_reax_bonds.html, "reax/c/species"_fix_reaxc_species.html, "rx"_fix_rx.html, "saed/vtk"_fix_saed_vtk.html, "shardlow"_fix_shardlow.html, "smd"_fix_smd.html, "smd/adjust/dt"_fix_smd_adjust_dt.html, "smd/integrate/tlsph"_fix_smd_integrate_tlsph.html, "smd/integrate/ulsph"_fix_smd_integrate_ulsph.html, "smd/move/triangulated/surface"_fix_smd_move_triangulated_surface.html, "smd/setvel"_fix_smd_setvel.html, "smd/wall/surface"_fix_smd_wall_surface.html, "temp/rescale/eff"_fix_temp_rescale_eff.html, "ti/spring"_fix_ti_spring.html, "ttm/mod"_fix_ttm.html :tb(c=6,ea=c) :line Compute styles :h4 See the "compute"_compute.html command for one-line descriptions of each style or click on the style itself for a full description. Some of the styles have accelerated versions, which can be used if LAMMPS is built with the "appropriate accelerated package"_Section_accelerate.html. This is indicated by additional letters in parenthesis: g = GPU, i = USER-INTEL, k = KOKKOS, o = USER-OMP, t = OPT. "angle"_compute_angle.html, "angle/local"_compute_angle_local.html, "angmom/chunk"_compute_angmom_chunk.html, "body/local"_compute_body_local.html, "bond"_compute_bond.html, "bond/local"_compute_bond_local.html, "centro/atom"_compute_centro_atom.html, "chunk/atom"_compute_chunk_atom.html, "cluster/atom"_compute_cluster_atom.html, "cna/atom"_compute_cna_atom.html, "com"_compute_com.html, "com/chunk"_compute_com_chunk.html, "contact/atom"_compute_contact_atom.html, "coord/atom"_compute_coord_atom.html, "damage/atom"_compute_damage_atom.html, "dihedral"_compute_dihedral.html, "dihedral/local"_compute_dihedral_local.html, "dilatation/atom"_compute_dilatation_atom.html, "dipole/chunk"_compute_dipole_chunk.html, "displace/atom"_compute_displace_atom.html, "erotate/asphere"_compute_erotate_asphere.html, "erotate/rigid"_compute_erotate_rigid.html, "erotate/sphere"_compute_erotate_sphere.html, "erotate/sphere/atom"_compute_erotate_sphere_atom.html, "event/displace"_compute_event_displace.html, "group/group"_compute_group_group.html, "gyration"_compute_gyration.html, "gyration/chunk"_compute_gyration_chunk.html, "heat/flux"_compute_heat_flux.html, "hexorder/atom"_compute_hexorder_atom.html, "improper"_compute_improper.html, "improper/local"_compute_improper_local.html, "inertia/chunk"_compute_inertia_chunk.html, "ke"_compute_ke.html, "ke/atom"_compute_ke_atom.html, "ke/rigid"_compute_ke_rigid.html, "msd"_compute_msd.html, "msd/chunk"_compute_msd_chunk.html, "msd/nongauss"_compute_msd_nongauss.html, "omega/chunk"_compute_omega_chunk.html, "orientorder/atom"_compute_orientorder_atom.html, "pair"_compute_pair.html, "pair/local"_compute_pair_local.html, "pe"_compute_pe.html, "pe/atom"_compute_pe_atom.html, "plasticity/atom"_compute_plasticity_atom.html, "pressure"_compute_pressure.html, "property/atom"_compute_property_atom.html, "property/local"_compute_property_local.html, "property/chunk"_compute_property_chunk.html, "rdf"_compute_rdf.html, "reduce"_compute_reduce.html, "reduce/region"_compute_reduce.html, "rigid/local"_compute_rigid_local.html, "slice"_compute_slice.html, "sna/atom"_compute_sna_atom.html, "snad/atom"_compute_sna_atom.html, "snav/atom"_compute_sna_atom.html, "stress/atom"_compute_stress_atom.html, "temp (k)"_compute_temp.html, "temp/asphere"_compute_temp_asphere.html, "temp/body"_compute_temp_body.html, "temp/chunk"_compute_temp_chunk.html, "temp/com"_compute_temp_com.html, "temp/deform"_compute_temp_deform.html, "temp/partial"_compute_temp_partial.html, "temp/profile"_compute_temp_profile.html, "temp/ramp"_compute_temp_ramp.html, "temp/region"_compute_temp_region.html, "temp/sphere"_compute_temp_sphere.html, "ti"_compute_ti.html, "torque/chunk"_compute_torque_chunk.html, "vacf"_compute_vacf.html, "vcm/chunk"_compute_vcm_chunk.html, "voronoi/atom"_compute_voronoi_atom.html :tb(c=6,ea=c) These are additional compute styles in USER packages, which can be used if "LAMMPS is built with the appropriate package"_Section_start.html#start_3. "ackland/atom"_compute_ackland_atom.html, "basal/atom"_compute_basal_atom.html, "dpd"_compute_dpd.html, "dpd/atom"_compute_dpd_atom.html, "fep"_compute_fep.html, "force/tally"_compute_tally.html, "heat/flux/tally"_compute_tally.html, "ke/eff"_compute_ke_eff.html, "ke/atom/eff"_compute_ke_atom_eff.html, "meso/e/atom"_compute_meso_e_atom.html, "meso/rho/atom"_compute_meso_rho_atom.html, "meso/t/atom"_compute_meso_t_atom.html, "pe/tally"_compute_tally.html, "pe/mol/tally"_compute_tally.html, "saed"_compute_saed.html, "smd/contact/radius"_compute_smd_contact_radius.html, "smd/damage"_compute_smd_damage.html, "smd/hourglass/error"_compute_smd_hourglass_error.html, "smd/internal/energy"_compute_smd_internal_energy.html, "smd/plastic/strain"_compute_smd_plastic_strain.html, "smd/plastic/strain/rate"_compute_smd_plastic_strain_rate.html, "smd/rho"_compute_smd_rho.html, "smd/tlsph/defgrad"_compute_smd_tlsph_defgrad.html, "smd/tlsph/dt"_compute_smd_tlsph_dt.html, "smd/tlsph/num/neighs"_compute_smd_tlsph_num_neighs.html, "smd/tlsph/shape"_compute_smd_tlsph_shape.html, "smd/tlsph/strain"_compute_smd_tlsph_strain.html, "smd/tlsph/strain/rate"_compute_smd_tlsph_strain_rate.html, "smd/tlsph/stress"_compute_smd_tlsph_stress.html, "smd/triangle/mesh/vertices"_compute_smd_triangle_mesh_vertices.html, "smd/ulsph/num/neighs"_compute_smd_ulsph_num_neighs.html, "smd/ulsph/strain"_compute_smd_ulsph_strain.html, "smd/ulsph/strain/rate"_compute_smd_ulsph_strain_rate.html, "smd/ulsph/stress"_compute_smd_ulsph_stress.html, "smd/vol"_compute_smd_vol.html, "stress/tally"_compute_tally.html, "temp/drude"_compute_temp_drude.html, "temp/eff"_compute_temp_eff.html, "temp/deform/eff"_compute_temp_deform_eff.html, "temp/region/eff"_compute_temp_region_eff.html, "temp/rotate"_compute_temp_rotate.html, "xrd"_compute_xrd.html :tb(c=6,ea=c) :line Pair_style potentials :h4 See the "pair_style"_pair_style.html command for an overview of pair potentials. Click on the style itself for a full description. Many of the styles have accelerated versions, which can be used if LAMMPS is built with the "appropriate accelerated package"_Section_accelerate.html. This is indicated by additional letters in parenthesis: g = GPU, i = USER-INTEL, k = KOKKOS, o = USER-OMP, t = OPT. "none"_pair_none.html, "zero"_pair_zero.html, "hybrid"_pair_hybrid.html, "hybrid/overlay"_pair_hybrid.html, "adp (o)"_pair_adp.html, "airebo (o)"_pair_airebo.html, "airebo/morse (o)"_pair_airebo.html, "beck (go)"_pair_beck.html, "body"_pair_body.html, "bop"_pair_bop.html, "born (go)"_pair_born.html, "born/coul/long (go)"_pair_born.html, "born/coul/long/cs"_pair_born.html, "born/coul/msm (o)"_pair_born.html, "born/coul/wolf (go)"_pair_born.html, "brownian (o)"_pair_brownian.html, "brownian/poly (o)"_pair_brownian.html, "buck (gkio)"_pair_buck.html, "buck/coul/cut (gkio)"_pair_buck.html, "buck/coul/long (gkio)"_pair_buck.html, "buck/coul/long/cs"_pair_buck.html, "buck/coul/msm (o)"_pair_buck.html, "buck/long/coul/long (o)"_pair_buck_long.html, "colloid (go)"_pair_colloid.html, "comb (o)"_pair_comb.html, "comb3"_pair_comb.html, "coul/cut (gko)"_pair_coul.html, "coul/debye (gko)"_pair_coul.html, "coul/dsf (gko)"_pair_coul.html, "coul/long (gko)"_pair_coul.html, "coul/long/cs"_pair_coul.html, "coul/msm"_pair_coul.html, "coul/streitz"_pair_coul.html, "coul/wolf (ko)"_pair_coul.html, "dpd (o)"_pair_dpd.html, "dpd/tstat (o)"_pair_dpd.html, "dsmc"_pair_dsmc.html, "eam (gkot)"_pair_eam.html, "eam/alloy (gkot)"_pair_eam.html, "eam/fs (gkot)"_pair_eam.html, "eim (o)"_pair_eim.html, "gauss (go)"_pair_gauss.html, "gayberne (gio)"_pair_gayberne.html, "gran/hertz/history (o)"_pair_gran.html, "gran/hooke (o)"_pair_gran.html, "gran/hooke/history (o)"_pair_gran.html, "hbond/dreiding/lj (o)"_pair_hbond_dreiding.html, "hbond/dreiding/morse (o)"_pair_hbond_dreiding.html, "kim"_pair_kim.html, "lcbop"_pair_lcbop.html, "line/lj"_pair_line_lj.html, "lj/charmm/coul/charmm (ko)"_pair_charmm.html, "lj/charmm/coul/charmm/implicit (ko)"_pair_charmm.html, "lj/charmm/coul/long (giko)"_pair_charmm.html, "lj/charmm/coul/msm"_pair_charmm.html, "lj/class2 (gko)"_pair_class2.html, "lj/class2/coul/cut (ko)"_pair_class2.html, "lj/class2/coul/long (gko)"_pair_class2.html, "lj/cubic (go)"_pair_lj_cubic.html, "lj/cut (gikot)"_pair_lj.html, "lj/cut/coul/cut (gko)"_pair_lj.html, "lj/cut/coul/debye (gko)"_pair_lj.html, "lj/cut/coul/dsf (gko)"_pair_lj.html, "lj/cut/coul/long (gikot)"_pair_lj.html, "lj/cut/coul/long/cs"_pair_lj.html, "lj/cut/coul/msm (go)"_pair_lj.html, "lj/cut/dipole/cut (go)"_pair_dipole.html, "lj/cut/dipole/long"_pair_dipole.html, "lj/cut/tip4p/cut (o)"_pair_lj.html, "lj/cut/tip4p/long (ot)"_pair_lj.html, "lj/expand (gko)"_pair_lj_expand.html, "lj/gromacs (gko)"_pair_gromacs.html, "lj/gromacs/coul/gromacs (ko)"_pair_gromacs.html, "lj/long/coul/long (o)"_pair_lj_long.html, "lj/long/dipole/long"_pair_dipole.html, "lj/long/tip4p/long"_pair_lj_long.html, "lj/smooth (o)"_pair_lj_smooth.html, "lj/smooth/linear (o)"_pair_lj_smooth_linear.html, "lj96/cut (go)"_pair_lj96.html, "lubricate (o)"_pair_lubricate.html, "lubricate/poly (o)"_pair_lubricate.html, "lubricateU"_pair_lubricateU.html, "lubricateU/poly"_pair_lubricateU.html, "meam"_pair_meam.html, "mie/cut (o)"_pair_mie.html, "morse (got)"_pair_morse.html, "nb3b/harmonic (o)"_pair_nb3b_harmonic.html, "nm/cut (o)"_pair_nm.html, "nm/cut/coul/cut (o)"_pair_nm.html, "nm/cut/coul/long (o)"_pair_nm.html, "peri/eps"_pair_peri.html, "peri/lps (o)"_pair_peri.html, "peri/pmb (o)"_pair_peri.html, "peri/ves"_pair_peri.html, "polymorphic"_pair_polymorphic.html, "reax"_pair_reax.html, "rebo (o)"_pair_airebo.html, "resquared (go)"_pair_resquared.html, "snap"_pair_snap.html, "soft (go)"_pair_soft.html, "sw (gkio)"_pair_sw.html, "table (gko)"_pair_table.html, "tersoff (gkio)"_pair_tersoff.html, "tersoff/mod (gko)"_pair_tersoff_mod.html, "tersoff/zbl (gko)"_pair_tersoff_zbl.html, "tip4p/cut (o)"_pair_coul.html, "tip4p/long (o)"_pair_coul.html, "tri/lj"_pair_tri_lj.html, "vashishta (o)"_pair_vashishta.html, "yukawa (go)"_pair_yukawa.html, "yukawa/colloid (go)"_pair_yukawa_colloid.html, "zbl (go)"_pair_zbl.html :tb(c=4,ea=c) These are additional pair styles in USER packages, which can be used if "LAMMPS is built with the appropriate package"_Section_start.html#start_3. "awpmd/cut"_pair_awpmd.html, "buck/mdf"_pair_mdf.html, "coul/cut/soft (o)"_pair_lj_soft.html, "coul/diel (o)"_pair_coul_diel.html, "coul/long/soft (o)"_pair_lj_soft.html, "dpd/fdt"_pair_dpd_fdt.html, "dpd/fdt/energy"_pair_dpd_fdt.html, "eam/cd (o)"_pair_eam.html, "edip (o)"_pair_edip.html, "eff/cut"_pair_eff.html, "exp6/rx"_pair_exp6_rx.html, "gauss/cut"_pair_gauss.html, "lennard/mdf"_pair_mdf.html, "list"_pair_list.html, "lj/charmm/coul/long/soft (o)"_pair_charmm.html, "lj/cut/coul/cut/soft (o)"_pair_lj_soft.html, "lj/cut/coul/long/soft (o)"_pair_lj_soft.html, "lj/cut/dipole/sf (go)"_pair_dipole.html, "lj/cut/soft (o)"_pair_lj_soft.html, "lj/cut/thole/long (o)"_pair_thole.html, "lj/cut/tip4p/long/soft (o)"_pair_lj_soft.html, "lj/mdf"_pair_mdf.html, "lj/sdk (gko)"_pair_sdk.html, "lj/sdk/coul/long (go)"_pair_sdk.html, "lj/sdk/coul/msm (o)"_pair_sdk.html, "lj/sf (o)"_pair_lj_sf.html, "meam/spline (o)"_pair_meam_spline.html, "meam/sw/spline"_pair_meam_sw_spline.html, "mgpt"_pair_mgpt.html, "morse/smooth/linear"_pair_morse.html, "morse/soft"_pair_morse.html, "multi/lucy"_pair_multi_lucy.html, "multi/lucy/rx"_pair_multi_lucy_rx.html, "quip"_pair_quip.html, "reax/c (k)"_pair_reax_c.html, "smd/hertz"_pair_smd_hertz.html, "smd/tlsph"_pair_smd_tlsph.html, "smd/triangulated/surface"_pair_smd_triangulated_surface.html, "smd/ulsph"_pair_smd_ulsph.html, "smtbq"_pair_smtbq.html, "sph/heatconduction"_pair_sph_heatconduction.html, "sph/idealgas"_pair_sph_idealgas.html, "sph/lj"_pair_sph_lj.html, "sph/rhosum"_pair_sph_rhosum.html, "sph/taitwater"_pair_sph_taitwater.html, "sph/taitwater/morris"_pair_sph_taitwater_morris.html, "srp"_pair_srp.html, "table/rx"_pair_table_rx.html, "tersoff/table (o)"_pair_tersoff.html, "thole"_pair_thole.html, "tip4p/long/soft (o)"_pair_lj_soft.html :tb(c=4,ea=c) :line Bond_style potentials :h4 See the "bond_style"_bond_style.html command for an overview of bond potentials. Click on the style itself for a full description. Some of the styles have accelerated versions, which can be used if LAMMPS is built with the "appropriate accelerated package"_Section_accelerate.html. This is indicated by additional letters in parenthesis: g = GPU, i = USER-INTEL, k = KOKKOS, o = USER-OMP, t = OPT. "none"_bond_none.html, "zero"_bond_zero.html, "hybrid"_bond_hybrid.html, "class2 (o)"_bond_class2.html, "fene (iko)"_bond_fene.html, "fene/expand (o)"_bond_fene_expand.html, "harmonic (ko)"_bond_harmonic.html, "morse (o)"_bond_morse.html, "nonlinear (o)"_bond_nonlinear.html, "quartic (o)"_bond_quartic.html, "table (o)"_bond_table.html :tb(c=4,ea=c) These are additional bond styles in USER packages, which can be used if "LAMMPS is built with the appropriate package"_Section_start.html#start_3. "harmonic/shift (o)"_bond_harmonic_shift.html, "harmonic/shift/cut (o)"_bond_harmonic_shift_cut.html :tb(c=4,ea=c) :line Angle_style potentials :h4 See the "angle_style"_angle_style.html command for an overview of angle potentials. Click on the style itself for a full description. Some of the styles have accelerated versions, which can be used if LAMMPS is built with the "appropriate accelerated package"_Section_accelerate.html. This is indicated by additional letters in parenthesis: g = GPU, i = USER-INTEL, k = KOKKOS, o = USER-OMP, t = OPT. "none"_angle_none.html, "zero"_angle_zero.html, "hybrid"_angle_hybrid.html, "charmm (ko)"_angle_charmm.html, "class2 (o)"_angle_class2.html, "cosine (o)"_angle_cosine.html, "cosine/delta (o)"_angle_cosine_delta.html, "cosine/periodic (o)"_angle_cosine_periodic.html, "cosine/squared (o)"_angle_cosine_squared.html, "harmonic (iko)"_angle_harmonic.html, "table (o)"_angle_table.html :tb(c=4,ea=c) These are additional angle styles in USER packages, which can be used if "LAMMPS is built with the appropriate package"_Section_start.html#start_3. "cosine/shift (o)"_angle_cosine_shift.html, "cosine/shift/exp (o)"_angle_cosine_shift_exp.html, "dipole (o)"_angle_dipole.html, "fourier (o)"_angle_fourier.html, "fourier/simple (o)"_angle_fourier_simple.html, "quartic (o)"_angle_quartic.html, "sdk"_angle_sdk.html :tb(c=4,ea=c) :line Dihedral_style potentials :h4 See the "dihedral_style"_dihedral_style.html command for an overview of dihedral potentials. Click on the style itself for a full description. Some of the styles have accelerated versions, which can be used if LAMMPS is built with the "appropriate accelerated package"_Section_accelerate.html. This is indicated by additional letters in parenthesis: g = GPU, i = USER-INTEL, k = KOKKOS, o = USER-OMP, t = OPT. "none"_dihedral_none.html, "zero"_dihedral_zero.html, "hybrid"_dihedral_hybrid.html, "charmm (ko)"_dihedral_charmm.html, "class2 (o)"_dihedral_class2.html, "harmonic (io)"_dihedral_harmonic.html, "helix (o)"_dihedral_helix.html, "multi/harmonic (o)"_dihedral_multi_harmonic.html, "opls (iko)"_dihedral_opls.html :tb(c=4,ea=c) These are additional dihedral styles in USER packages, which can be used if "LAMMPS is built with the appropriate package"_Section_start.html#start_3. "cosine/shift/exp (o)"_dihedral_cosine_shift_exp.html, "fourier (o)"_dihedral_fourier.html, "nharmonic (o)"_dihedral_nharmonic.html, "quadratic (o)"_dihedral_quadratic.html, "spherical (o)"_dihedral_spherical.html, "table (o)"_dihedral_table.html :tb(c=4,ea=c) :line Improper_style potentials :h4 See the "improper_style"_improper_style.html command for an overview of improper potentials. Click on the style itself for a full description. Some of the styles have accelerated versions, which can be used if LAMMPS is built with the "appropriate accelerated package"_Section_accelerate.html. This is indicated by additional letters in parenthesis: g = GPU, i = USER-INTEL, k = KOKKOS, o = USER-OMP, t = OPT. "none"_improper_none.html, "zero"_improper_zero.html, "hybrid"_improper_hybrid.html, "class2 (o)"_improper_class2.html, "cvff (io)"_improper_cvff.html, "harmonic (ko)"_improper_harmonic.html, "umbrella (o)"_improper_umbrella.html :tb(c=4,ea=c) These are additional improper styles in USER packages, which can be used if "LAMMPS is built with the appropriate package"_Section_start.html#start_3. "cossq (o)"_improper_cossq.html, "distance"_improper_distance.html, "fourier (o)"_improper_fourier.html, "ring (o)"_improper_ring.html :tb(c=4,ea=c) :line Kspace solvers :h4 See the "kspace_style"_kspace_style.html command for an overview of Kspace solvers. Click on the style itself for a full description. Some of the styles have accelerated versions, which can be used if LAMMPS is built with the "appropriate accelerated package"_Section_accelerate.html. This is indicated by additional letters in parenthesis: g = GPU, i = USER-INTEL, k = KOKKOS, o = USER-OMP, t = OPT. "ewald (o)"_kspace_style.html, "ewald/disp"_kspace_style.html, "msm (o)"_kspace_style.html, "msm/cg (o)"_kspace_style.html, "pppm (go)"_kspace_style.html, "pppm/cg (o)"_kspace_style.html, "pppm/disp"_kspace_style.html, "pppm/disp/tip4p"_kspace_style.html, "pppm/stagger"_kspace_style.html, "pppm/tip4p (o)"_kspace_style.html :tb(c=4,ea=c) diff --git a/doc/src/Section_example.txt b/doc/src/Section_example.txt index b84c52edb..60a5ed128 100644 --- a/doc/src/Section_example.txt +++ b/doc/src/Section_example.txt @@ -1,140 +1,140 @@ "Previous Section"_Section_howto.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next Section"_Section_perf.html :c :link(lws,http://lammps.sandia.gov) :link(ld,Manual.html) :link(lc,Section_commands.html#comm) :line 7. Example problems :h3 The LAMMPS distribution includes an examples sub-directory with many sample problems. Many are 2d models that run quickly are are straightforward to visualize, requiring at most a couple of minutes to run on a desktop machine. Each problem has an input script (in.*) and produces a log file (log.*) when it runs. Some use a data file (data.*) of initial coordinates as additional input. A few sample log file run on different machines and different numbers of processors are included in the directories to compare your answers to. E.g. a log file like log.date.crack.foo.P means the "crack" example was run on P processors of machine "foo" on that date (i.e. with that version of LAMMPS). Many of the input files have commented-out lines for creating dump files and image files. If you uncomment the "dump"_dump.html command in the input script, a text dump file will be produced, which can be animated by various "visualization programs"_http://lammps.sandia.gov/viz.html. It can also be animated using the xmovie tool described in the "Additional Tools"_Section_tools.html section of the LAMMPS documentation. If you uncomment the "dump image"_dump.html command in the input script, and assuming you have built LAMMPS with a JPG library, JPG snapshot images will be produced when the simulation runs. They can be quickly post-processed into a movie using commands described on the "dump image"_dump_image.html doc page. Animations of many of the examples can be viewed on the Movies section of the "LAMMPS web site"_lws. There are two kinds of sub-directories in the examples dir. Lowercase dirs contain one or a few simple, quick-to-run problems. Uppercase dirs contain up to several complex scripts that illustrate a particular kind of simulation method or model. Some of these run for longer times, e.g. to measure a particular quantity. Lists of both kinds of directories are given below. :line Lowercase directories :h4 accelerate: run with various acceleration options (OpenMP, GPU, Phi) balance: dynamic load balancing, 2d system body: body particles, 2d system colloid: big colloid particles in a small particle solvent, 2d system -comb: models using the COMB potential +comb: models using the COMB potential coreshell: core/shell model using CORESHELL package -crack: crack propagation in a 2d solid +crack: crack propagation in a 2d solid deposit: deposit atoms and molecules on a surface dipole: point dipolar particles, 2d system dreiding: methanol via Dreiding FF eim: NaCl using the EIM potential ellipse: ellipsoidal particles in spherical solvent, 2d system -flow: Couette and Poiseuille flow in a 2d channel +flow: Couette and Poiseuille flow in a 2d channel friction: frictional contact of spherical asperities between 2d surfaces hugoniostat: Hugoniostat shock dynamics -indent: spherical indenter into a 2d solid +indent: spherical indenter into a 2d solid kim: use of potentials in Knowledge Base for Interatomic Models (KIM) -meam: MEAM test for SiC and shear (same as shear examples) -melt: rapid melt of 3d LJ system +meam: MEAM test for SiC and shear (same as shear examples) +melt: rapid melt of 3d LJ system micelle: self-assembly of small lipid-like molecules into 2d bilayers -min: energy minimization of 2d LJ melt -msst: MSST shock dynamics +min: energy minimization of 2d LJ melt +msst: MSST shock dynamics nb3b: use of nonbonded 3-body harmonic pair style -neb: nudged elastic band (NEB) calculation for barrier finding -nemd: non-equilibrium MD of 2d sheared system +neb: nudged elastic band (NEB) calculation for barrier finding +nemd: non-equilibrium MD of 2d sheared system obstacle: flow around two voids in a 2d channel peptide: dynamics of a small solvated peptide chain (5-mer) -peri: Peridynamic model of cylinder impacted by indenter +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 python: using embedded Python in a LAMMPS input script qeq: use of the QEQ package 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 snap: NVE dynamics for BCC tantalum crystal using SNAP potential srd: stochastic rotation dynamics (SRD) particles as solvent streitz: use of Streitz/Mintmire potential with charge equilibration tad: temperature-accelerated dynamics of vacancy diffusion in bulk Si vashishta: use of the Vashishta potential :tb(s=:) Here is how you can run and visualize one of the sample problems: cd indent cp ../../src/lmp_linux . # copy LAMMPS executable to this dir lmp_linux -in in.indent # run the problem :pre Running the simulation produces the files {dump.indent} and {log.lammps}. You can visualize the dump file of snapshots with a variety of 3rd-party tools highlighted on the "Visualization"_http://lammps.sandia.gov/viz.html page of the LAMMPS web site. If you uncomment the "dump image"_dump_image.html line(s) in the input script a series of JPG images will be produced by the run (assuming you built LAMMPS with JPG support; see "Section 2.2"_Section_start.html#start_2 for details). These can be viewed individually or turned into a movie or animated by tools like ImageMagick or QuickTime or various Windows-based tools. See the "dump image"_dump_image.html doc page for more details. E.g. this Imagemagick command would create a GIF file suitable for viewing in a browser. % convert -loop 1 *.jpg foo.gif :pre :line Uppercase directories :h4 ASPHERE: various aspherical particle models, using ellipsoids, rigid bodies, line/triangle particles, etc COUPLE: examples of how to use LAMMPS as a library DIFFUSE: compute diffusion coefficients via several methods ELASTIC: compute elastic constants at zero temperature ELASTIC_T: compute elastic constants at finite temperature KAPPA: compute thermal conductivity via several methods MC: using LAMMPS in a Monte Carlo mode to relax the energy of a system USER: examples for USER packages and USER-contributed commands VISCOSITY: compute viscosity via several methods :tb(s=:) Nearly all of these directories have README files which give more details on how to understand and use their contents. The USER directory has a large number of sub-directories which correspond by name to a USER package. They contain scripts that illustrate how to use the command(s) provided in that package. Many of the sub-directories have their own README files which give further instructions. See the "Section 4"_Section_packages.html doc page for more info on specific USER packages. diff --git a/doc/src/Section_history.txt b/doc/src/Section_history.txt index cae765f50..438284c9d 100644 --- a/doc/src/Section_history.txt +++ b/doc/src/Section_history.txt @@ -1,135 +1,135 @@ "Previous Section"_Section_errors.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next Section"_Manual.html :c :link(lws,http://lammps.sandia.gov) :link(ld,Manual.html) :link(lc,Section_commands.html#comm) :line 13. Future and history :h3 This section lists features we plan to add to LAMMPS, features of previous versions of LAMMPS, and features of other parallel molecular dynamics codes our group has distributed. 13.1 "Coming attractions"_#hist_1 13.2 "Past versions"_#hist_2 :all(b) :line :line 13.1 Coming attractions :h4,link(hist_1) As of summer 2016 we are using the "LAMMPS project issue tracker on GitHub"_https://github.com/lammps/lammps/issues for keeping track of suggested, planned or pending new features. This includes discussions of how to best implement them, or why they would be useful. Especially if a planned or proposed feature is non-trivial to add, e.g. because it requires changes to some of the core classes of LAMMPS, people planning to contribute a new feature to LAMMS are encouraged to submit an issue about their planned implementation this way in order to receive feedback from the LAMMPS core developers. They will provide suggestions about the validity of the proposed approach and possible improvements, pitfalls or alternatives. Please see some of the closed issues for examples of how to suggest code enhancements, submit proposed changes, or report -elated issues and how they are resoved. +possible bugs and how they are resoved. As an alternative to using GitHub, you may e-mail the "core developers"_http://lammps.sandia.gov/authors.html or send an e-mail to the "LAMMPS Mail list"_http://lammps.sandia.gov/mail.html if you want to have your suggestion added to the list. :line 13.2 Past versions :h4,link(hist_2) LAMMPS development began in the mid 1990s under a cooperative research & development agreement (CRADA) between two DOE labs (Sandia and LLNL) and 3 companies (Cray, Bristol Myers Squibb, and Dupont). The goal was to develop a large-scale parallel classical MD code; the coding effort was led by Steve Plimpton at Sandia. After the CRADA ended, a final F77 version, LAMMPS 99, was released. As development of LAMMPS continued at Sandia, its memory management was converted to F90; a final F90 version was released as LAMMPS 2001. The current LAMMPS is a rewrite in C++ and was first publicly released as an open source code in 2004. It includes many new features beyond those in LAMMPS 99 or 2001. It also includes features from older parallel MD codes written at Sandia, namely ParaDyn, Warp, and GranFlow (see below). In late 2006 we began merging new capabilities into LAMMPS that were developed by Aidan Thompson at Sandia for his MD code GRASP, which has a parallel framework similar to LAMMPS. Most notably, these have included many-body potentials - Stillinger-Weber, Tersoff, ReaxFF - and the associated charge-equilibration routines needed for ReaxFF. The "History link"_http://lammps.sandia.gov/history.html on the LAMMPS WWW page gives a timeline of features added to the C++ open-source version of LAMMPS over the last several years. These older codes are available for download from the "LAMMPS WWW site"_lws, except for Warp & GranFlow which were primarily used internally. A brief listing of their features is given here. LAMMPS 2001 F90 + MPI dynamic memory spatial-decomposition parallelism NVE, NVT, NPT, NPH, rRESPA integrators LJ and Coulombic pairwise force fields all-atom, united-atom, bead-spring polymer force fields CHARMM-compatible force fields class 2 force fields 3d/2d Ewald & PPPM various force and temperature constraints SHAKE Hessian-free truncated-Newton minimizer user-defined diagnostics :ul LAMMPS 99 F77 + MPI static memory allocation spatial-decomposition parallelism most of the LAMMPS 2001 features with a few exceptions no 2d Ewald & PPPM molecular force fields are missing a few CHARMM terms no SHAKE :ul Warp F90 + MPI spatial-decomposition parallelism embedded atom method (EAM) metal potentials + LJ lattice and grain-boundary atom creation NVE, NVT integrators boundary conditions for applying shear stresses temperature controls for actively sheared systems per-atom energy and centro-symmetry computation and output :ul ParaDyn F77 + MPI atom- and force-decomposition parallelism embedded atom method (EAM) metal potentials lattice atom creation NVE, NVT, NPT integrators all serial DYNAMO features for controls and constraints :ul GranFlow F90 + MPI spatial-decomposition parallelism frictional granular potentials NVE integrator boundary conditions for granular flow and packing and walls particle insertion :ul diff --git a/doc/src/Section_howto.txt b/doc/src/Section_howto.txt index 5ad1de31b..8dbec55e7 100644 --- a/doc/src/Section_howto.txt +++ b/doc/src/Section_howto.txt @@ -1,2826 +1,2826 @@ "Previous Section"_Section_accelerate.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next Section"_Section_example.html :c :link(lws,http://lammps.sandia.gov) :link(ld,Manual.html) :link(lc,Section_commands.html#comm) :line 6. How-to discussions :h3 This section describes how to perform common tasks using LAMMPS. 6.1 "Restarting a simulation"_#howto_1 6.2 "2d simulations"_#howto_2 6.3 "CHARMM, AMBER, and DREIDING force fields"_#howto_3 6.4 "Running multiple simulations from one input script"_#howto_4 6.5 "Multi-replica simulations"_#howto_5 6.6 "Granular models"_#howto_6 6.7 "TIP3P water model"_#howto_7 6.8 "TIP4P water model"_#howto_8 6.9 "SPC water model"_#howto_9 6.10 "Coupling LAMMPS to other codes"_#howto_10 6.11 "Visualizing LAMMPS snapshots"_#howto_11 6.12 "Triclinic (non-orthogonal) simulation boxes"_#howto_12 6.13 "NEMD simulations"_#howto_13 6.14 "Finite-size spherical and aspherical particles"_#howto_14 6.15 "Output from LAMMPS (thermo, dumps, computes, fixes, variables)"_#howto_15 6.16 "Thermostatting, barostatting and computing temperature"_#howto_16 6.17 "Walls"_#howto_17 6.18 "Elastic constants"_#howto_18 6.19 "Library interface to LAMMPS"_#howto_19 6.20 "Calculating thermal conductivity"_#howto_20 6.21 "Calculating viscosity"_#howto_21 6.22 "Calculating a diffusion coefficient"_#howto_22 6.23 "Using chunks to calculate system properties"_#howto_23 6.24 "Setting parameters for the kspace_style pppm/disp command"_#howto_24 6.25 "Polarizable models"_#howto_25 6.26 "Adiabatic core/shell model"_#howto_26 6.27 "Drude induced dipoles"_#howto_27 :all(b) The example input scripts included in the LAMMPS distribution and highlighted in "Section 7"_Section_example.html also show how to setup and run various kinds of simulations. :line :line 6.1 Restarting a simulation :link(howto_1),h4 There are 3 ways to continue a long LAMMPS simulation. Multiple "run"_run.html commands can be used in the same input script. Each run will continue from where the previous run left off. Or binary restart files can be saved to disk using the "restart"_restart.html command. At a later time, these binary files can be read via a "read_restart"_read_restart.html command in a new script. Or they can be converted to text data files using the "-r command-line switch"_Section_start.html#start_7 and read by a "read_data"_read_data.html command in a new script. Here we give examples of 2 scripts that read either a binary restart file or a converted data file and then issue a new run command to continue where the previous run left off. They illustrate what settings must be made in the new script. Details are discussed in the documentation for the "read_restart"_read_restart.html and "read_data"_read_data.html commands. Look at the {in.chain} input script provided in the {bench} directory of the LAMMPS distribution to see the original script that these 2 scripts are based on. If that script had the line -restart 50 tmp.restart :pre +restart 50 tmp.restart :pre added to it, it would produce 2 binary restart files (tmp.restart.50 and tmp.restart.100) as it ran. This script could be used to read the 1st restart file and re-run the last 50 timesteps: -read_restart tmp.restart.50 :pre +read_restart tmp.restart.50 :pre -neighbor 0.4 bin -neigh_modify every 1 delay 1 :pre +neighbor 0.4 bin +neigh_modify every 1 delay 1 :pre -fix 1 all nve -fix 2 all langevin 1.0 1.0 10.0 904297 :pre +fix 1 all nve +fix 2 all langevin 1.0 1.0 10.0 904297 :pre -timestep 0.012 :pre +timestep 0.012 :pre -run 50 :pre +run 50 :pre Note that the following commands do not need to be repeated because their settings are included in the restart file: {units, atom_style, special_bonds, pair_style, bond_style}. However these commands do need to be used, since their settings are not in the restart file: {neighbor, fix, timestep}. If you actually use this script to perform a restarted run, you will notice that the thermodynamic data match at step 50 (if you also put a "thermo 50" command in the original script), but do not match at step 100. This is because the "fix langevin"_fix_langevin.html command uses random numbers in a way that does not allow for perfect restarts. As an alternate approach, the restart file could be converted to a data file as follows: lmp_g++ -r tmp.restart.50 tmp.restart.data :pre Then, this script could be used to re-run the last 50 steps: -units lj -atom_style bond -pair_style lj/cut 1.12 -pair_modify shift yes -bond_style fene +units lj +atom_style bond +pair_style lj/cut 1.12 +pair_modify shift yes +bond_style fene special_bonds 0.0 1.0 1.0 :pre -read_data tmp.restart.data :pre +read_data tmp.restart.data :pre -neighbor 0.4 bin -neigh_modify every 1 delay 1 :pre +neighbor 0.4 bin +neigh_modify every 1 delay 1 :pre -fix 1 all nve -fix 2 all langevin 1.0 1.0 10.0 904297 :pre +fix 1 all nve +fix 2 all langevin 1.0 1.0 10.0 904297 :pre -timestep 0.012 :pre +timestep 0.012 :pre -reset_timestep 50 -run 50 :pre +reset_timestep 50 +run 50 :pre Note that nearly all the settings specified in the original {in.chain} script must be repeated, except the {pair_coeff} and {bond_coeff} commands since the new data file lists the force field coefficients. Also, the "reset_timestep"_reset_timestep.html command is used to tell LAMMPS the current timestep. This value is stored in restart files, but not in data files. :line 6.2 2d simulations :link(howto_2),h4 Use the "dimension"_dimension.html command to specify a 2d simulation. Make the simulation box periodic in z via the "boundary"_boundary.html command. This is the default. If using the "create box"_create_box.html command to define a simulation box, set the z dimensions narrow, but finite, so that the create_atoms command will tile the 3d simulation box with a single z plane of atoms - e.g. "create box"_create_box.html 1 -10 10 -10 10 -0.25 0.25 :pre If using the "read data"_read_data.html command to read in a file of atom coordinates, set the "zlo zhi" values to be finite but narrow, similar to the create_box command settings just described. For each atom in the file, assign a z coordinate so it falls inside the z-boundaries of the box - e.g. 0.0. Use the "fix enforce2d"_fix_enforce2d.html command as the last defined fix to insure that the z-components of velocities and forces are zeroed out every timestep. The reason to make it the last fix is so that any forces induced by other fixes will be zeroed out. Many of the example input scripts included in the LAMMPS distribution are for 2d models. NOTE: Some models in LAMMPS treat particles as finite-size spheres, as opposed to point particles. In 2d, the particles will still be spheres, not disks, meaning their moment of inertia will be the same as in 3d. :line 6.3 CHARMM, AMBER, and DREIDING force fields :link(howto_3),h4 A force field has 2 parts: the formulas that define it and the coefficients used for a particular system. Here we only discuss formulas implemented in LAMMPS that correspond to formulas commonly used in the CHARMM, AMBER, and DREIDING force fields. Setting coefficients is done in the input data file via the "read_data"_read_data.html command or in the input script with commands like "pair_coeff"_pair_coeff.html or "bond_coeff"_bond_coeff.html. See "Section 9"_Section_tools.html for additional tools that can use CHARMM or AMBER to assign force field coefficients and convert their output into LAMMPS input. See "(MacKerell)"_#howto-MacKerell for a description of the CHARMM force field. See "(Cornell)"_#howto-Cornell for a description of the AMBER force field. :link(charmm,http://www.scripps.edu/brooks) :link(amber,http://amber.scripps.edu) These style choices compute force field formulas that are consistent with common options in CHARMM or AMBER. See each command's documentation for the formula it computes. "bond_style"_bond_harmonic.html harmonic "angle_style"_angle_charmm.html charmm "dihedral_style"_dihedral_charmm.html charmm "pair_style"_pair_charmm.html lj/charmm/coul/charmm "pair_style"_pair_charmm.html lj/charmm/coul/charmm/implicit "pair_style"_pair_charmm.html lj/charmm/coul/long :ul "special_bonds"_special_bonds.html charmm "special_bonds"_special_bonds.html amber :ul DREIDING is a generic force field developed by the "Goddard group"_http://www.wag.caltech.edu at Caltech and is useful for predicting structures and dynamics of organic, biological and main-group inorganic molecules. The philosophy in DREIDING is to use general force constants and geometry parameters based on simple hybridization considerations, rather than individual force constants and geometric parameters that depend on the particular combinations of atoms involved in the bond, angle, or torsion terms. DREIDING has an "explicit hydrogen bond term"_pair_hbond_dreiding.html to describe interactions involving a hydrogen atom on very electronegative atoms (N, O, F). See "(Mayo)"_#howto-Mayo for a description of the DREIDING force field These style choices compute force field formulas that are consistent with the DREIDING force field. See each command's documentation for the formula it computes. "bond_style"_bond_harmonic.html harmonic "bond_style"_bond_morse.html morse :ul "angle_style"_angle_harmonic.html harmonic "angle_style"_angle_cosine.html cosine "angle_style"_angle_cosine_periodic.html cosine/periodic :ul "dihedral_style"_dihedral_charmm.html charmm "improper_style"_improper_umbrella.html umbrella :ul "pair_style"_pair_buck.html buck "pair_style"_pair_buck.html buck/coul/cut "pair_style"_pair_buck.html buck/coul/long "pair_style"_pair_lj.html lj/cut "pair_style"_pair_lj.html lj/cut/coul/cut "pair_style"_pair_lj.html lj/cut/coul/long :ul "pair_style"_pair_hbond_dreiding.html hbond/dreiding/lj "pair_style"_pair_hbond_dreiding.html hbond/dreiding/morse :ul "special_bonds"_special_bonds.html dreiding :ul :line 6.4 Running multiple simulations from one input script :link(howto_4),h4 This can be done in several ways. See the documentation for individual commands for more details on how these examples work. If "multiple simulations" means continue a previous simulation for more timesteps, then you simply use the "run"_run.html command multiple times. For example, this script units lj atom_style atomic read_data data.lj run 10000 run 10000 run 10000 run 10000 run 10000 :pre would run 5 successive simulations of the same system for a total of 50,000 timesteps. If you wish to run totally different simulations, one after the other, the "clear"_clear.html command can be used in between them to re-initialize LAMMPS. For example, this script units lj atom_style atomic read_data data.lj run 10000 clear units lj atom_style atomic read_data data.lj.new run 10000 :pre would run 2 independent simulations, one after the other. For large numbers of independent simulations, you can use "variables"_variable.html and the "next"_next.html and "jump"_jump.html commands to loop over the same input script multiple times with different settings. For example, this script, named in.polymer variable d index run1 run2 run3 run4 run5 run6 run7 run8 shell cd $d read_data data.polymer run 10000 shell cd .. clear next d jump in.polymer :pre would run 8 simulations in different directories, using a data.polymer file in each directory. The same concept could be used to run the same system at 8 different temperatures, using a temperature variable and storing the output in different log and dump files, for example variable a loop 8 variable t index 0.8 0.85 0.9 0.95 1.0 1.05 1.1 1.15 log log.$a read data.polymer velocity all create $t 352839 fix 1 all nvt $t $t 100.0 dump 1 all atom 1000 dump.$a run 100000 clear next t next a jump in.polymer :pre All of the above examples work whether you are running on 1 or multiple processors, but assumed you are running LAMMPS on a single partition of processors. LAMMPS can be run on multiple partitions via the "-partition" command-line switch as described in "this section"_Section_start.html#start_7 of the manual. In the last 2 examples, if LAMMPS were run on 3 partitions, the same scripts could be used if the "index" and "loop" variables were replaced with {universe}-style variables, as described in the "variable"_variable.html command. Also, the "next t" and "next a" commands would need to be replaced with a single "next a t" command. With these modifications, the 8 simulations of each script would run on the 3 partitions one after the other until all were finished. Initially, 3 simulations would be started simultaneously, one on each partition. When one finished, that partition would then start the 4th simulation, and so forth, until all 8 were completed. :line 6.5 Multi-replica simulations :link(howto_5),h4 Several commands in LAMMPS run mutli-replica simulations, meaning that multiple instances (replicas) of your simulation are run simultaneously, with small amounts of data exchanged between replicas periodically. These are the relevant commands: "neb"_neb.html for nudged elastic band calculations "prd"_prd.html for parallel replica dynamics "tad"_tad.html for temperature accelerated dynamics "temper"_temper.html for parallel tempering "fix pimd"_fix_pimd.html for path-integral molecular dynamics (PIMD) :ul NEB is a method for finding transition states and barrier energies. PRD and TAD are methods for performing accelerated dynamics to find and perform infrequent events. Parallel tempering or replica exchange runs different replicas at a series of temperature to facilitate rare-event sampling. These commands can only be used if LAMMPS was built with the REPLICA package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info on packages. PIMD runs different replicas whose individual particles are coupled together by springs to model a system or ring-polymers. This commands can only be used if LAMMPS was built with the USER-MISC package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info on packages. In all these cases, you must run with one or more processors per replica. The processors assigned to each replica are determined at run-time by using the "-partition command-line switch"_Section_start.html#start_7 to launch LAMMPS on multiple partitions, which in this context are the same as replicas. E.g. these commands: mpirun -np 16 lmp_linux -partition 8x2 -in in.temper mpirun -np 8 lmp_linux -partition 8x1 -in in.neb :pre would each run 8 replicas, on either 16 or 8 processors. Note the use of the "-in command-line switch"_Section_start.html#start_7 to specify the input script which is required when running in multi-replica mode. Also note that with MPI installed on a machine (e.g. your desktop), you can run on more (virtual) processors than you have physical processors. Thus the above commands could be run on a single-processor (or few-processor) desktop so that you can run a multi-replica simulation on more replicas than you have physical processors. :line 6.6 Granular models :link(howto_6),h4 Granular system are composed of spherical particles with a diameter, as opposed to point particles. This means they have an angular velocity and torque can be imparted to them to cause them to rotate. To run a simulation of a granular model, you will want to use the following commands: "atom_style sphere"_atom_style.html "fix nve/sphere"_fix_nve_sphere.html "fix gravity"_fix_gravity.html :ul This compute "compute erotate/sphere"_compute_erotate_sphere.html :ul calculates rotational kinetic energy which can be "output with thermodynamic info"_Section_howto.html#howto_15. Use one of these 3 pair potentials, which compute forces and torques between interacting pairs of particles: "pair_style"_pair_style.html gran/history "pair_style"_pair_style.html gran/no_history "pair_style"_pair_style.html gran/hertzian :ul These commands implement fix options specific to granular systems: "fix freeze"_fix_freeze.html "fix pour"_fix_pour.html "fix viscous"_fix_viscous.html "fix wall/gran"_fix_wall_gran.html :ul The fix style {freeze} zeroes both the force and torque of frozen atoms, and should be used for granular system instead of the fix style {setforce}. For computational efficiency, you can eliminate needless pairwise computations between frozen atoms by using this command: "neigh_modify"_neigh_modify.html exclude :ul :line 6.7 TIP3P water model :link(howto_7),h4 The TIP3P water model as implemented in CHARMM "(MacKerell)"_#howto-MacKerell specifies a 3-site rigid water molecule with charges and Lennard-Jones parameters assigned to each of the 3 atoms. In LAMMPS the "fix shake"_fix_shake.html command can be used to hold the two O-H bonds and the H-O-H angle rigid. A bond style of {harmonic} and an angle style of {harmonic} or {charmm} should also be used. These are the additional parameters (in real units) to set for O and H atoms and the water molecule to run a rigid TIP3P-CHARMM model with a cutoff. The K values can be used if a flexible TIP3P model (without fix shake) is desired. If the LJ epsilon and sigma for HH and OH are set to 0.0, it corresponds to the original 1983 TIP3P model "(Jorgensen)"_#Jorgensen. O mass = 15.9994 H mass = 1.008 O charge = -0.834 H charge = 0.417 LJ epsilon of OO = 0.1521 LJ sigma of OO = 3.1507 LJ epsilon of HH = 0.0460 LJ sigma of HH = 0.4000 LJ epsilon of OH = 0.0836 LJ sigma of OH = 1.7753 K of OH bond = 450 r0 of OH bond = 0.9572 K of HOH angle = 55 theta of HOH angle = 104.52 :all(b),p These are the parameters to use for TIP3P with a long-range Coulombic solver (e.g. Ewald or PPPM in LAMMPS), see "(Price)"_#Price for details: O mass = 15.9994 H mass = 1.008 O charge = -0.830 H charge = 0.415 LJ epsilon of OO = 0.102 LJ sigma of OO = 3.188 LJ epsilon, sigma of OH, HH = 0.0 K of OH bond = 450 r0 of OH bond = 0.9572 K of HOH angle = 55 theta of HOH angle = 104.52 :all(b),p Wikipedia also has a nice article on "water models"_http://en.wikipedia.org/wiki/Water_model. :line 6.8 TIP4P water model :link(howto_8),h4 The four-point TIP4P rigid water model extends the traditional three-point TIP3P model by adding an additional site, usually massless, where the charge associated with the oxygen atom is placed. This site M is located at a fixed distance away from the oxygen along the bisector of the HOH bond angle. A bond style of {harmonic} and an angle style of {harmonic} or {charmm} should also be used. A TIP4P model is run with LAMMPS using either this command for a cutoff model: "pair_style lj/cut/tip4p/cut"_pair_lj.html or these two commands for a long-range model: "pair_style lj/cut/tip4p/long"_pair_lj.html "kspace_style pppm/tip4p"_kspace_style.html :ul For both models, the bond lengths and bond angles should be held fixed using the "fix shake"_fix_shake.html command. These are the additional parameters (in real units) to set for O and H atoms and the water molecule to run a rigid TIP4P model with a cutoff "(Jorgensen)"_#Jorgensen. Note that the OM distance is specified in the "pair_style"_pair_style.html command, not as part of the pair coefficients. O mass = 15.9994 H mass = 1.008 O charge = -1.040 H charge = 0.520 r0 of OH bond = 0.9572 theta of HOH angle = 104.52 OM distance = 0.15 LJ epsilon of O-O = 0.1550 LJ sigma of O-O = 3.1536 LJ epsilon, sigma of OH, HH = 0.0 Coulombic cutoff = 8.5 :all(b),p For the TIP4/Ice model (J Chem Phys, 122, 234511 (2005); http://dx.doi.org/10.1063/1.1931662) these values can be used: O mass = 15.9994 H mass = 1.008 O charge = -1.1794 H charge = 0.5897 r0 of OH bond = 0.9572 theta of HOH angle = 104.52 OM distance = 0.1577 LJ epsilon of O-O = 0.21084 LJ sigma of O-O = 3.1668 LJ epsilon, sigma of OH, HH = 0.0 Coulombic cutoff = 8.5 :all(b),p For the TIP4P/2005 model (J Chem Phys, 123, 234505 (2005); http://dx.doi.org/10.1063/1.2121687), these values can be used: O mass = 15.9994 H mass = 1.008 O charge = -1.1128 H charge = 0.5564 r0 of OH bond = 0.9572 theta of HOH angle = 104.52 OM distance = 0.1546 LJ epsilon of O-O = 0.1852 LJ sigma of O-O = 3.1589 LJ epsilon, sigma of OH, HH = 0.0 Coulombic cutoff = 8.5 :all(b),p These are the parameters to use for TIP4P with a long-range Coulombic solver (e.g. Ewald or PPPM in LAMMPS): O mass = 15.9994 H mass = 1.008 O charge = -1.0484 H charge = 0.5242 r0 of OH bond = 0.9572 theta of HOH angle = 104.52 OM distance = 0.1250 LJ epsilon of O-O = 0.16275 LJ sigma of O-O = 3.16435 LJ epsilon, sigma of OH, HH = 0.0 :all(b),p Note that the when using the TIP4P pair style, the neighobr list cutoff for Coulomb interactions is effectively extended by a distance 2 * (OM distance), to account for the offset distance of the fictitious charges on O atoms in water molecules. Thus it is typically best in an efficiency sense to use a LJ cutoff >= Coulomb cutoff + 2*(OM distance), to shrink the size of the neighbor list. This leads to slightly larger cost for the long-range calculation, so you can test the trade-off for your model. The OM distance and the LJ and Coulombic cutoffs are set in the "pair_style lj/cut/tip4p/long"_pair_lj.html command. Wikipedia also has a nice article on "water models"_http://en.wikipedia.org/wiki/Water_model. :line 6.9 SPC water model :link(howto_9),h4 The SPC water model specifies a 3-site rigid water molecule with charges and Lennard-Jones parameters assigned to each of the 3 atoms. In LAMMPS the "fix shake"_fix_shake.html command can be used to hold the two O-H bonds and the H-O-H angle rigid. A bond style of {harmonic} and an angle style of {harmonic} or {charmm} should also be used. These are the additional parameters (in real units) to set for O and H atoms and the water molecule to run a rigid SPC model. O mass = 15.9994 H mass = 1.008 O charge = -0.820 H charge = 0.410 LJ epsilon of OO = 0.1553 LJ sigma of OO = 3.166 LJ epsilon, sigma of OH, HH = 0.0 r0 of OH bond = 1.0 theta of HOH angle = 109.47 :all(b),p Note that as originally proposed, the SPC model was run with a 9 Angstrom cutoff for both LJ and Coulommbic terms. It can also be used with long-range Coulombics (Ewald or PPPM in LAMMPS), without changing any of the parameters above, though it becomes a different model in that mode of usage. The SPC/E (extended) water model is the same, except the partial charge assignemnts change: O charge = -0.8476 H charge = 0.4238 :all(b),p See the "(Berendsen)"_#howto-Berendsen reference for more details on both the SPC and SPC/E models. Wikipedia also has a nice article on "water models"_http://en.wikipedia.org/wiki/Water_model. :line 6.10 Coupling LAMMPS to other codes :link(howto_10),h4 LAMMPS is designed to allow it to be coupled to other codes. For example, a quantum mechanics code might compute forces on a subset of atoms and pass those forces to LAMMPS. Or a continuum finite element (FE) simulation might use atom positions as boundary conditions on FE nodal points, compute a FE solution, and return interpolated forces on MD atoms. LAMMPS can be coupled to other codes in at least 3 ways. Each has advantages and disadvantages, which you'll have to think about in the context of your application. (1) Define a new "fix"_fix.html command that calls the other code. In this scenario, LAMMPS is the driver code. During its timestepping, the fix is invoked, and can make library calls to the other code, which has been linked to LAMMPS as a library. This is the way the "POEMS"_poems package that performs constrained rigid-body motion on groups of atoms is hooked to LAMMPS. See the "fix poems"_fix_poems.html command for more details. See "this section"_Section_modify.html of the documentation for info on how to add a new fix to LAMMPS. :link(poems,http://www.rpi.edu/~anderk5/lab) (2) Define a new LAMMPS command that calls the other code. This is conceptually similar to method (1), but in this case LAMMPS and the other code are on a more equal footing. Note that now the other code is not called during the timestepping of a LAMMPS run, but between runs. The LAMMPS input script can be used to alternate LAMMPS runs with calls to the other code, invoked via the new command. The "run"_run.html command facilitates this with its {every} option, which makes it easy to run a few steps, invoke the command, run a few steps, invoke the command, etc. In this scenario, the other code can be called as a library, as in (1), or it could be a stand-alone code, invoked by a system() call made by the command (assuming your parallel machine allows one or more processors to start up another program). In the latter case the stand-alone code could communicate with LAMMPS thru files that the command writes and reads. See "Section 10"_Section_modify.html of the documentation for how to add a new command to LAMMPS. (3) Use LAMMPS as a library called by another code. In this case the other code is the driver and calls LAMMPS as needed. Or a wrapper code could link and call both LAMMPS and another code as libraries. Again, the "run"_run.html command has options that allow it to be invoked with minimal overhead (no setup or clean-up) if you wish to do multiple short runs, driven by another program. Examples of driver codes that call LAMMPS as a library are included in the examples/COUPLE directory of the LAMMPS distribution; see examples/COUPLE/README for more details: simple: simple driver programs in C++ and C which invoke LAMMPS as a library :ulb,l lammps_quest: coupling of LAMMPS and "Quest"_quest, to run classical MD with quantum forces calculated by a density functional code :l lammps_spparks: coupling of LAMMPS and "SPPARKS"_spparks, to couple a kinetic Monte Carlo model for grain growth using MD to calculate strain induced across grain boundaries :l :ule :link(quest,http://dft.sandia.gov/Quest) :link(spparks,http://www.sandia.gov/~sjplimp/spparks.html) "This section"_Section_start.html#start_5 of the documentation describes how to build LAMMPS as a library. Once this is done, you can interface with LAMMPS either via C++, C, Fortran, or Python (or any other language that supports a vanilla C-like interface). For example, from C++ you could create one (or more) "instances" of LAMMPS, pass it an input script to process, or execute individual commands, all by invoking the correct class methods in LAMMPS. From C or Fortran you can make function calls to do the same things. See "Section 11"_Section_python.html of the manual for a description of the Python wrapper provided with LAMMPS that operates through the LAMMPS library interface. The files src/library.cpp and library.h contain the C-style interface to LAMMPS. See "Section 6.19"_Section_howto.html#howto_19 of the manual for a description of the interface and how to extend it for your needs. Note that the lammps_open() function that creates an instance of LAMMPS takes an MPI communicator as an argument. This means that instance of LAMMPS will run on the set of processors in the communicator. Thus the calling code can run LAMMPS on all or a subset of processors. For example, a wrapper script might decide to alternate between LAMMPS and another code, allowing them both to run on all the processors. Or it might allocate half the processors to LAMMPS and half to the other code and run both codes simultaneously before syncing them up periodically. Or it might instantiate multiple instances of LAMMPS to perform different calculations. :line 6.11 Visualizing LAMMPS snapshots :link(howto_11),h4 LAMMPS itself does not do visualization, but snapshots from LAMMPS simulations can be visualized (and analyzed) in a variety of ways. LAMMPS snapshots are created by the "dump"_dump.html command which can create files in several formats. The native LAMMPS dump format is a text file (see "dump atom" or "dump custom") which can be visualized by the "xmovie"_Section_tools.html#xmovie program, included with the LAMMPS package. This produces simple, fast 2d projections of 3d systems, and can be useful for rapid debugging of simulation geometry and atom trajectories. Several programs included with LAMMPS as auxiliary tools can convert native LAMMPS dump files to other formats. See the "Section 9"_Section_tools.html doc page for details. The first is the "ch2lmp tool"_Section_tools.html#charmm, which contains a lammps2pdb Perl script which converts LAMMPS dump files into PDB files. The second is the "lmp2arc tool"_Section_tools.html#arc which converts LAMMPS dump files into Accelrys' Insight MD program files. The third is the "lmp2cfg tool"_Section_tools.html#cfg which converts LAMMPS dump files into CFG files which can be read into the "AtomEye"_atomeye visualizer. A Python-based toolkit distributed by our group can read native LAMMPS dump files, including custom dump files with additional columns of user-specified atom information, and convert them to various formats or pipe them into visualization software directly. See the "Pizza.py WWW site"_pizza for details. Specifically, Pizza.py can convert LAMMPS dump files into PDB, XYZ, "Ensight"_ensight, and VTK formats. Pizza.py can pipe LAMMPS dump files directly into the Raster3d and RasMol visualization programs. Pizza.py has tools that do interactive 3d OpenGL visualization and one that creates SVG images of dump file snapshots. LAMMPS can create XYZ files directly (via "dump xyz") which is a simple text-based file format used by many visualization programs including "VMD"_vmd. LAMMPS can create DCD files directly (via "dump dcd") which can be read by "VMD"_vmd in conjunction with a CHARMM PSF file. Using this form of output avoids the need to convert LAMMPS snapshots to PDB files. See the "dump"_dump.html command for more information on DCD files. LAMMPS can create XTC files directly (via "dump xtc") which is GROMACS file format which can also be read by "VMD"_vmd for visualization. See the "dump"_dump.html command for more information on XTC files. :link(pizza,http://www.sandia.gov/~sjplimp/pizza.html) :link(vmd,http://www.ks.uiuc.edu/Research/vmd) :link(ensight,http://www.ensight.com) :link(atomeye,http://mt.seas.upenn.edu/Archive/Graphics/A) :line 6.12 Triclinic (non-orthogonal) simulation boxes :link(howto_12),h4 By default, LAMMPS uses an orthogonal simulation box to encompass the particles. The "boundary"_boundary.html command sets the boundary conditions of the box (periodic, non-periodic, etc). The orthogonal box has its "origin" at (xlo,ylo,zlo) and is defined by 3 edge vectors starting from the origin given by [a] = (xhi-xlo,0,0); [b] = (0,yhi-ylo,0); [c] = (0,0,zhi-zlo). The 6 parameters (xlo,xhi,ylo,yhi,zlo,zhi) are defined at the time the simulation box is created, e.g. by the "create_box"_create_box.html or "read_data"_read_data.html or "read_restart"_read_restart.html commands. Additionally, LAMMPS defines box size parameters lx,ly,lz where lx = xhi-xlo, and similarly in the y and z dimensions. The 6 parameters, as well as lx,ly,lz, can be output via the "thermo_style custom"_thermo_style.html command. LAMMPS also allows simulations to be performed in triclinic (non-orthogonal) simulation boxes shaped as a parallelepiped with triclinic symmetry. The parallelepiped has its "origin" at (xlo,ylo,zlo) and is defined by 3 edge vectors starting from the origin given by [a] = (xhi-xlo,0,0); [b] = (xy,yhi-ylo,0); [c] = (xz,yz,zhi-zlo). {xy,xz,yz} can be 0.0 or positive or negative values and are called "tilt factors" because they are the amount of displacement applied to faces of an originally orthogonal box to transform it into the parallelepiped. In LAMMPS the triclinic simulation box edge vectors [a], [b], and [c] cannot be arbitrary vectors. As indicated, [a] must lie on the positive x axis. [b] must lie in the xy plane, with strictly positive y component. [c] may have any orientation with strictly positive z component. The requirement that [a], [b], and [c] have strictly positive x, y, and z components, respectively, ensures that [a], [b], and [c] form a complete right-handed basis. These restrictions impose no loss of generality, since it is possible to rotate/invert any set of 3 crystal basis vectors so that they conform to the restrictions. For example, assume that the 3 vectors [A],[B],[C] are the edge vectors of a general parallelepiped, where there is no restriction on [A],[B],[C] other than they form a complete right-handed basis i.e. [A] x [B] . [C] > 0. The equivalent LAMMPS [a],[b],[c] are a linear rotation of [A], [B], and [C] and can be computed as follows: :c,image(Eqs/transform.jpg) where A = | [A] | indicates the scalar length of [A]. The hat symbol (^) indicates the corresponding unit vector. {beta} and {gamma} are angles between the vectors described below. Note that by construction, [a], [b], and [c] have strictly positive x, y, and z components, respectively. If it should happen that [A], [B], and [C] form a left-handed basis, then the above equations are not valid for [c]. In this case, it is necessary to first apply an inversion. This can be achieved by interchanging two basis vectors or by changing the sign of one of them. For consistency, the same rotation/inversion applied to the basis vectors must also be applied to atom positions, velocities, and any other vector quantities. This can be conveniently achieved by first converting to fractional coordinates in the old basis and then converting to distance coordinates in the new basis. The transformation is given by the following equation: :c,image(Eqs/rotate.jpg) where {V} is the volume of the box, [X] is the original vector quantity and [x] is the vector in the LAMMPS basis. There is no requirement that a triclinic box be periodic in any dimension, though it typically should be in at least the 2nd dimension of the tilt (y in xy) if you want to enforce a shift in periodic boundary conditions across that boundary. Some commands that work with triclinic boxes, e.g. the "fix deform"_fix_deform.html and "fix npt"_fix_nh.html commands, require periodicity or non-shrink-wrap boundary conditions in specific dimensions. See the command doc pages for details. The 9 parameters (xlo,xhi,ylo,yhi,zlo,zhi,xy,xz,yz) are defined at the time the simluation box is created. This happens in one of 3 ways. If the "create_box"_create_box.html command is used with a region of style {prism}, then a triclinic box is setup. See the "region"_region.html command for details. If the "read_data"_read_data.html command is used to define the simulation box, and the header of the data file contains a line with the "xy xz yz" keyword, then a triclinic box is setup. See the "read_data"_read_data.html command for details. Finally, if the "read_restart"_read_restart.html command reads a restart file which was written from a simulation using a triclinic box, then a triclinic box will be setup for the restarted simulation. Note that you can define a triclinic box with all 3 tilt factors = 0.0, so that it is initially orthogonal. This is necessary if the box will become non-orthogonal, e.g. due to the "fix npt"_fix_nh.html or "fix deform"_fix_deform.html commands. Alternatively, you can use the "change_box"_change_box.html command to convert a simulation box from orthogonal to triclinic and vice versa. As with orthogonal boxes, LAMMPS defines triclinic box size parameters lx,ly,lz where lx = xhi-xlo, and similarly in the y and z dimensions. The 9 parameters, as well as lx,ly,lz, can be output via the "thermo_style custom"_thermo_style.html command. To avoid extremely tilted boxes (which would be computationally inefficient), LAMMPS normally requires that no tilt factor can skew the box more than half the distance of the parallel box length, which is the 1st dimension in the tilt factor (x for xz). This is required both when the simulation box is created, e.g. via the "create_box"_create_box.html or "read_data"_read_data.html commands, as well as when the box shape changes dynamically during a simulation, e.g. via the "fix deform"_fix_deform.html or "fix npt"_fix_nh.html commands. For example, if xlo = 2 and xhi = 12, then the x box length is 10 and the xy tilt factor must be between -5 and 5. Similarly, both xz and yz must be between -(xhi-xlo)/2 and +(yhi-ylo)/2. Note that this is not a limitation, since if the maximum tilt factor is 5 (as in this example), then configurations with tilt = ..., -15, -5, 5, 15, 25, ... are geometrically all equivalent. If the box tilt exceeds this limit during a dynamics run (e.g. via the "fix deform"_fix_deform.html command), then the box is "flipped" to an equivalent shape with a tilt factor within the bounds, so the run can continue. See the "fix deform"_fix_deform.html doc page for further details. One exception to this rule is if the 1st dimension in the tilt factor (x for xy) is non-periodic. In that case, the limits on the tilt factor are not enforced, since flipping the box in that dimension does not change the atom positions due to non-periodicity. In this mode, if you tilt the system to extreme angles, the simulation will simply become inefficient, due to the highly skewed simulation box. The limitation on not creating a simulation box with a tilt factor skewing the box more than half the distance of the parallel box length can be overridden via the "box"_box.html command. Setting the {tilt} keyword to {large} allows any tilt factors to be specified. Box flips that may occur using the "fix deform"_fix_deform.html or "fix npt"_fix_nh.html commands can be turned off using the {flip no} option with either of the commands. Note that if a simulation box has a large tilt factor, LAMMPS will run less efficiently, due to the large volume of communication needed to acquire ghost atoms around a processor's irregular-shaped sub-domain. For extreme values of tilt, LAMMPS may also lose atoms and generate an error. Triclinic crystal structures are often defined using three lattice constants {a}, {b}, and {c}, and three angles {alpha}, {beta} and {gamma}. Note that in this nomenclature, the a, b, and c lattice constants are the scalar lengths of the edge vectors [a], [b], and [c] defined above. The relationship between these 6 quantities (a,b,c,alpha,beta,gamma) and the LAMMPS box sizes (lx,ly,lz) = (xhi-xlo,yhi-ylo,zhi-zlo) and tilt factors (xy,xz,yz) is as follows: :c,image(Eqs/box.jpg) The inverse relationship can be written as follows: :c,image(Eqs/box_inverse.jpg) The values of {a}, {b}, {c} , {alpha}, {beta} , and {gamma} can be printed out or accessed by computes using the "thermo_style custom"_thermo_style.html keywords {cella}, {cellb}, {cellc}, {cellalpha}, {cellbeta}, {cellgamma}, respectively. As discussed on the "dump"_dump.html command doc page, when the BOX BOUNDS for a snapshot is written to a dump file for a triclinic box, an orthogonal bounding box which encloses the triclinic simulation box is output, along with the 3 tilt factors (xy, xz, yz) of the triclinic box, formatted as follows: ITEM: BOX BOUNDS xy xz yz xlo_bound xhi_bound xy ylo_bound yhi_bound xz zlo_bound zhi_bound yz :pre This bounding box is convenient for many visualization programs and is calculated from the 9 triclinic box parameters (xlo,xhi,ylo,yhi,zlo,zhi,xy,xz,yz) as follows: xlo_bound = xlo + MIN(0.0,xy,xz,xy+xz) xhi_bound = xhi + MAX(0.0,xy,xz,xy+xz) ylo_bound = ylo + MIN(0.0,yz) yhi_bound = yhi + MAX(0.0,yz) zlo_bound = zlo zhi_bound = zhi :pre These formulas can be inverted if you need to convert the bounding box back into the triclinic box parameters, e.g. xlo = xlo_bound - MIN(0.0,xy,xz,xy+xz). One use of triclinic simulation boxes is to model solid-state crystals with triclinic symmetry. The "lattice"_lattice.html command can be used with non-orthogonal basis vectors to define a lattice that will tile a triclinic simulation box via the "create_atoms"_create_atoms.html command. A second use is to run Parinello-Rahman dyanamics via the "fix npt"_fix_nh.html command, which will adjust the xy, xz, yz tilt factors to compensate for off-diagonal components of the pressure tensor. The analalog for an "energy minimization"_minimize.html is the "fix box/relax"_fix_box_relax.html command. A third use is to shear a bulk solid to study the response of the material. The "fix deform"_fix_deform.html command can be used for this purpose. It allows dynamic control of the xy, xz, yz tilt factors as a simulation runs. This is discussed in the next section on non-equilibrium MD (NEMD) simulations. :line 6.13 NEMD simulations :link(howto_13),h4 Non-equilibrium molecular dynamics or NEMD simulations are typically used to measure a fluid's rheological properties such as viscosity. In LAMMPS, such simulations can be performed by first setting up a non-orthogonal simulation box (see the preceding Howto section). A shear strain can be applied to the simulation box at a desired strain rate by using the "fix deform"_fix_deform.html command. The "fix nvt/sllod"_fix_nvt_sllod.html command can be used to thermostat the sheared fluid and integrate the SLLOD equations of motion for the system. Fix nvt/sllod uses "compute temp/deform"_compute_temp_deform.html to compute a thermal temperature by subtracting out the streaming velocity of the shearing atoms. The velocity profile or other properties of the fluid can be monitored via the "fix ave/chunk"_fix_ave_chunk.html command. As discussed in the previous section on non-orthogonal simulation boxes, the amount of tilt or skew that can be applied is limited by LAMMPS for computational efficiency to be 1/2 of the parallel box length. However, "fix deform"_fix_deform.html can continuously strain a box by an arbitrary amount. As discussed in the "fix deform"_fix_deform.html command, when the tilt value reaches a limit, the box is flipped to the opposite limit which is an equivalent tiling of periodic space. The strain rate can then continue to change as before. In a long NEMD simulation these box re-shaping events may occur many times. In a NEMD simulation, the "remap" option of "fix deform"_fix_deform.html should be set to "remap v", since that is what "fix nvt/sllod"_fix_nvt_sllod.html assumes to generate a velocity profile consistent with the applied shear strain rate. An alternative method for calculating viscosities is provided via the "fix viscosity"_fix_viscosity.html command. :line 6.14 Finite-size spherical and aspherical particles :link(howto_14),h4 Typical MD models treat atoms or particles as point masses. Sometimes it is desirable to have a model with finite-size particles such as spheroids or ellipsoids or generalized aspherical bodies. The difference is that such particles have a moment of inertia, rotational energy, and angular momentum. Rotation is induced by torque coming from interactions with other particles. LAMMPS has several options for running simulations with these kinds of particles. The following aspects are discussed in turn: atom styles pair potentials time integration computes, thermodynamics, and dump output rigid bodies composed of finite-size particles :ul Example input scripts for these kinds of models are in the body, colloid, dipole, ellipse, line, peri, pour, and tri directories of the "examples directory"_Section_example.html in the LAMMPS distribution. Atom styles :h5 There are several "atom styles"_atom_style.html that allow for definition of finite-size particles: sphere, dipole, ellipsoid, line, tri, peri, and body. The sphere style defines particles that are spheriods and each particle can have a unique diameter and mass (or density). These particles store an angular velocity (omega) and can be acted upon by torque. The "set" command can be used to modify the diameter and mass of individual particles, after then are created. The dipole style does not actually define finite-size particles, but is often used in conjunction with spherical particles, via a command like atom_style hybrid sphere dipole :pre This is because when dipoles interact with each other, they induce torques, and a particle must be finite-size (i.e. have a moment of inertia) in order to respond and rotate. See the "atom_style dipole"_atom_style.html command for details. The "set" command can be used to modify the orientation and length of the dipole moment of individual particles, after then are created. The ellipsoid style defines particles that are ellipsoids and thus can be aspherical. Each particle has a shape, specified by 3 diameters, and mass (or density). These particles store an angular momentum and their orientation (quaternion), and can be acted upon by torque. They do not store an angular velocity (omega), which can be in a different direction than angular momentum, rather they compute it as needed. The "set" command can be used to modify the diameter, orientation, and mass of individual particles, after then are created. It also has a brief explanation of what quaternions are. The line style defines line segment particles with two end points and a mass (or density). They can be used in 2d simulations, and they can be joined together to form rigid bodies which represent arbitrary polygons. The tri style defines triangular particles with three corner points and a mass (or density). They can be used in 3d simulations, and they can be joined together to form rigid bodies which represent arbitrary particles with a triangulated surface. The peri style is used with "Peridynamic models"_pair_peri.html and defines particles as having a volume, that is used internally in the "pair_style peri"_pair_peri.html potentials. The body style allows for definition of particles which can represent complex entities, such as surface meshes of discrete points, collections of sub-particles, deformable objects, etc. The body style is discussed in more detail on the "body"_body.html doc page. Note that if one of these atom styles is used (or multiple styles via the "atom_style hybrid"_atom_style.html command), not all particles in the system are required to be finite-size or aspherical. For example, in the ellipsoid style, if the 3 shape parameters are set to the same value, the particle will be a sphere rather than an ellipsoid. If the 3 shape parameters are all set to 0.0 or if the diameter is set to 0.0, it will be a point particle. In the line or tri style, if the lineflag or triflag is specified as 0, then it will be a point particle. Some of the pair styles used to compute pairwise interactions between finite-size particles also compute the correct interaction with point particles as well, e.g. the interaction between a point particle and a finite-size particle or between two point particles. If necessary, "pair_style hybrid"_pair_hybrid.html can be used to insure the correct interactions are computed for the appropriate style of interactions. Likewise, using groups to partition particles (ellipsoids versus spheres versus point particles) will allow you to use the appropriate time integrators and temperature computations for each class of particles. See the doc pages for various commands for details. Also note that for "2d simulations"_dimension.html, atom styles sphere and ellipsoid still use 3d particles, rather than as circular disks or ellipses. This means they have the same moment of inertia as the 3d object. When temperature is computed, the correct degrees of freedom are used for rotation in a 2d versus 3d system. Pair potentials :h5 When a system with finite-size particles is defined, the particles will only rotate and experience torque if the force field computes such interactions. These are the various "pair styles"_pair_style.html that generate torque: "pair_style gran/history"_pair_gran.html "pair_style gran/hertzian"_pair_gran.html "pair_style gran/no_history"_pair_gran.html "pair_style dipole/cut"_pair_dipole.html "pair_style gayberne"_pair_gayberne.html "pair_style resquared"_pair_resquared.html "pair_style brownian"_pair_brownian.html "pair_style lubricate"_pair_lubricate.html "pair_style line/lj"_pair_line_lj.html "pair_style tri/lj"_pair_tri_lj.html "pair_style body"_pair_body.html :ul The granular pair styles are used with spherical particles. The dipole pair style is used with the dipole atom style, which could be applied to spherical or ellipsoidal particles. The GayBerne and REsquared potentials require ellipsoidal particles, though they will also work if the 3 shape parameters are the same (a sphere). The Brownian and lubrication potentials are used with spherical particles. The line, tri, and body potentials are used with line segment, triangular, and body particles respectively. Time integration :h5 There are several fixes that perform time integration on finite-size spherical particles, meaning the integrators update the rotational orientation and angular velocity or angular momentum of the particles: "fix nve/sphere"_fix_nve_sphere.html "fix nvt/sphere"_fix_nvt_sphere.html "fix npt/sphere"_fix_npt_sphere.html :ul Likewise, there are 3 fixes that perform time integration on ellipsoidal particles: "fix nve/asphere"_fix_nve_asphere.html "fix nvt/asphere"_fix_nvt_asphere.html "fix npt/asphere"_fix_npt_asphere.html :ul The advantage of these fixes is that those which thermostat the particles include the rotational degrees of freedom in the temperature calculation and thermostatting. The "fix langevin"_fix_langevin command can also be used with its {omgea} or {angmom} options to thermostat the rotational degrees of freedom for spherical or ellipsoidal particles. Other thermostatting fixes only operate on the translational kinetic energy of finite-size particles. These fixes perform constant NVE time integration on line segment, triangular, and body particles: "fix nve/line"_fix_nve_line.html "fix nve/tri"_fix_nve_tri.html "fix nve/body"_fix_nve_body.html :ul Note that for mixtures of point and finite-size particles, these integration fixes can only be used with "groups"_group.html which contain finite-size particles. Computes, thermodynamics, and dump output :h5 There are several computes that calculate the temperature or rotational energy of spherical or ellipsoidal particles: "compute temp/sphere"_compute_temp_sphere.html "compute temp/asphere"_compute_temp_asphere.html "compute erotate/sphere"_compute_erotate_sphere.html "compute erotate/asphere"_compute_erotate_asphere.html :ul These include rotational degrees of freedom in their computation. If you wish the thermodynamic output of temperature or pressure to use one of these computes (e.g. for a system entirely composed of finite-size particles), then the compute can be defined and the "thermo_modify"_thermo_modify.html command used. Note that by default thermodynamic quantities will be calculated with a temperature that only includes translational degrees of freedom. See the "thermo_style"_thermo_style.html command for details. These commands can be used to output various attributes of finite-size particles: "dump custom"_dump.html "compute property/atom"_compute_property_atom.html "dump local"_dump.html "compute body/local"_compute_body_local.html :ul Attributes include the dipole moment, the angular velocity, the angular momentum, the quaternion, the torque, the end-point and corner-point coordinates (for line and tri particles), and sub-particle attributes of body particles. Rigid bodies composed of finite-size particles :h5 The "fix rigid"_fix_rigid.html command treats a collection of particles as a rigid body, computes its inertia tensor, sums the total force and torque on the rigid body each timestep due to forces on its constituent particles, and integrates the motion of the rigid body. If any of the constituent particles of a rigid body are finite-size particles (spheres or ellipsoids or line segments or triangles), then their contribution to the inertia tensor of the body is different than if they were point particles. This means the rotational dynamics of the rigid body will be different. Thus a model of a dimer is different if the dimer consists of two point masses versus two spheroids, even if the two particles have the same mass. Finite-size particles that experience torque due to their interaction with other particles will also impart that torque to a rigid body they are part of. See the "fix rigid" command for example of complex rigid-body models it is possible to define in LAMMPS. Note that the "fix shake"_fix_shake.html command can also be used to treat 2, 3, or 4 particles as a rigid body, but it always assumes the particles are point masses. Also note that body particles cannot be modeled with the "fix rigid"_fix_rigid.html command. Body particles are treated by LAMMPS as single particles, though they can store internal state, such as a list of sub-particles. Individual body partices are typically treated as rigid bodies, and their motion integrated with a command like "fix nve/body"_fix_nve_body.html. Interactions between pairs of body particles are computed via a command like "pair_style body"_pair_body.html. :line 6.15 Output from LAMMPS (thermo, dumps, computes, fixes, variables) :link(howto_15),h4 There are four basic kinds of LAMMPS output: "Thermodynamic output"_thermo_style.html, which is a list of quantities printed every few timesteps to the screen and logfile. :ulb,l "Dump files"_dump.html, which contain snapshots of atoms and various per-atom values and are written at a specified frequency. :l Certain fixes can output user-specified quantities to files: "fix ave/time"_fix_ave_time.html for time averaging, "fix ave/chunk"_fix_ave_chunk.html for spatial or other averaging, and "fix print"_fix_print.html for single-line output of "variables"_variable.html. Fix print can also output to the screen. :l "Restart files"_restart.html. :l :ule A simulation prints one set of thermodynamic output and (optionally) restart files. It can generate any number of dump files and fix output files, depending on what "dump"_dump.html and "fix"_fix.html commands you specify. As discussed below, LAMMPS gives you a variety of ways to determine what quantities are computed and printed when the thermodynamics, dump, or fix commands listed above perform output. Throughout this discussion, note that users can also "add their own computes and fixes to LAMMPS"_Section_modify.html which can then generate values that can then be output with these commands. The following sub-sections discuss different LAMMPS command related to output and the kind of data they operate on and produce: "Global/per-atom/local data"_#global "Scalar/vector/array data"_#scalar "Thermodynamic output"_#thermo "Dump file output"_#dump "Fixes that write output files"_#fixoutput "Computes that process output quantities"_#computeoutput "Fixes that process output quantities"_#fixprocoutput "Computes that generate values to output"_#compute "Fixes that generate values to output"_#fix "Variables that generate values to output"_#variable "Summary table of output options and data flow between commands"_#table :ul Global/per-atom/local data :h5,link(global) Various output-related commands work with three different styles of data: global, per-atom, or local. A global datum is one or more system-wide values, e.g. the temperature of the system. A per-atom datum is one or more values per atom, e.g. the kinetic energy of each atom. Local datums are calculated by each processor based on the atoms it owns, but there may be zero or more per atom, e.g. a list of bond distances. Scalar/vector/array data :h5,link(scalar) Global, per-atom, and local datums can each come in three kinds: a single scalar value, a vector of values, or a 2d array of values. The doc page for a "compute" or "fix" or "variable" that generates data will specify both the style and kind of data it produces, e.g. a per-atom vector. When a quantity is accessed, as in many of the output commands discussed below, it can be referenced via the following bracket notation, where ID in this case is the ID of a compute. The leading "c_" would be replaced by "f_" for a fix, or "v_" for a variable: c_ID | entire scalar, vector, or array c_ID\[I\] | one element of vector, one column of array c_ID\[I\]\[J\] | one element of array :tb(s=|) In other words, using one bracket reduces the dimension of the data once (vector -> scalar, array -> vector). Using two brackets reduces the dimension twice (array -> scalar). Thus a command that uses scalar values as input can typically also process elements of a vector or array. Thermodynamic output :h5,link(thermo) The frequency and format of thermodynamic output is set by the "thermo"_thermo.html, "thermo_style"_thermo_style.html, and "thermo_modify"_thermo_modify.html commands. The "thermo_style"_thermo_style.html command also specifies what values are calculated and written out. Pre-defined keywords can be specified (e.g. press, etotal, etc). Three additional kinds of keywords can also be specified (c_ID, f_ID, v_name), where a "compute"_compute.html or "fix"_fix.html or "variable"_variable.html provides the value to be output. In each case, the compute, fix, or variable must generate global values for input to the "thermo_style custom"_dump.html command. Note that thermodynamic output values can be "extensive" or "intensive". The former scale with the number of atoms in the system (e.g. total energy), the latter do not (e.g. temperature). The setting for "thermo_modify norm"_thermo_modify.html determines whether extensive quantities are normalized or not. Computes and fixes produce either extensive or intensive values; see their individual doc pages for details. "Equal-style variables"_variable.html produce only intensive values; you can include a division by "natoms" in the formula if desired, to make an extensive calculation produce an intensive result. Dump file output :h5,link(dump) Dump file output is specified by the "dump"_dump.html and "dump_modify"_dump_modify.html commands. There are several pre-defined formats (dump atom, dump xtc, etc). There is also a "dump custom"_dump.html format where the user specifies what values are output with each atom. Pre-defined atom attributes can be specified (id, x, fx, etc). Three additional kinds of keywords can also be specified (c_ID, f_ID, v_name), where a "compute"_compute.html or "fix"_fix.html or "variable"_variable.html provides the values to be output. In each case, the compute, fix, or variable must generate per-atom values for input to the "dump custom"_dump.html command. There is also a "dump local"_dump.html format where the user specifies what local values to output. A pre-defined index keyword can be specified to enumuerate the local values. Two additional kinds of keywords can also be specified (c_ID, f_ID), where a "compute"_compute.html or "fix"_fix.html or "variable"_variable.html provides the values to be output. In each case, the compute or fix must generate local values for input to the "dump local"_dump.html command. Fixes that write output files :h5,link(fixoutput) Several fixes take various quantities as input and can write output files: "fix ave/time"_fix_ave_time.html, "fix ave/chunk"_fix_ave_chunk.html, "fix ave/histo"_fix_ave_histo.html, "fix ave/correlate"_fix_ave_correlate.html, and "fix print"_fix_print.html. The "fix ave/time"_fix_ave_time.html command enables direct output to a file and/or time-averaging of global scalars or vectors. The user specifies one or more quantities as input. These can be global "compute"_compute.html values, global "fix"_fix.html values, or "variables"_variable.html of any style except the atom style which produces per-atom values. Since a variable can refer to keywords used by the "thermo_style custom"_thermo_style.html command (like temp or press) and individual per-atom values, a wide variety of quantities can be time averaged and/or output in this way. If the inputs are one or more scalar values, then the fix generate a global scalar or vector of output. If the inputs are one or more vector values, then the fix generates a global vector or array of output. The time-averaged output of this fix can also be used as input to other output commands. The "fix ave/chunk"_fix_ave_chunk.html command enables direct output to a file of chunk-averaged per-atom quantities like those output in dump files. Chunks can represent spatial bins or other collections of atoms, e.g. individual molecules. The per-atom quantities can be atom density (mass or number) or atom attributes such as position, velocity, force. They can also be per-atom quantities calculated by a "compute"_compute.html, by a "fix"_fix.html, or by an atom-style "variable"_variable.html. The chunk-averaged output of this fix can also be used as input to other output commands. The "fix ave/histo"_fix_ave_histo.html command enables direct output to a file of histogrammed quantities, which can be global or per-atom or local quantities. The histogram output of this fix can also be used as input to other output commands. The "fix ave/correlate"_fix_ave_correlate.html command enables direct output to a file of time-correlated quantities, which can be global values. The correlation matrix output of this fix can also be used as input to other output commands. The "fix print"_fix_print.html command can generate a line of output written to the screen and log file or to a separate file, periodically during a running simulation. The line can contain one or more "variable"_variable.html values for any style variable except the vector or atom styles). As explained above, variables themselves can contain references to global values generated by "thermodynamic keywords"_thermo_style.html, "computes"_compute.html, "fixes"_fix.html, or other "variables"_variable.html, or to per-atom values for a specific atom. Thus the "fix print"_fix_print.html command is a means to output a wide variety of quantities separate from normal thermodynamic or dump file output. Computes that process output quantities :h5,link(computeoutput) The "compute reduce"_compute_reduce.html and "compute reduce/region"_compute_reduce.html commands take one or more per-atom or local vector quantities as inputs and "reduce" them (sum, min, max, ave) to scalar quantities. These are produced as output values which can be used as input to other output commands. The "compute slice"_compute_slice.html command take one or more global vector or array quantities as inputs and extracts a subset of their values to create a new vector or array. These are produced as output values which can be used as input to other output commands. The "compute property/atom"_compute_property_atom.html command takes a list of one or more pre-defined atom attributes (id, x, fx, etc) and stores the values in a per-atom vector or array. These are produced as output values which can be used as input to other output commands. The list of atom attributes is the same as for the "dump custom"_dump.html command. The "compute property/local"_compute_property_local.html command takes a list of one or more pre-defined local attributes (bond info, angle info, etc) and stores the values in a local vector or array. These are produced as output values which can be used as input to other output commands. Fixes that process output quantities :h5,link(fixprocoutput) The "fix vector"_fix_vector.html command can create global vectors as output from global scalars as input, accumulating them one element at a time. The "fix ave/atom"_fix_ave_atom.html command performs time-averaging of per-atom vectors. The per-atom quantities can be atom attributes such as position, velocity, force. They can also be per-atom quantities calculated by a "compute"_compute.html, by a "fix"_fix.html, or by an atom-style "variable"_variable.html. The time-averaged per-atom output of this fix can be used as input to other output commands. The "fix store/state"_fix_store_state.html command can archive one or more per-atom attributes at a particular time, so that the old values can be used in a future calculation or output. The list of atom attributes is the same as for the "dump custom"_dump.html command, including per-atom quantities calculated by a "compute"_compute.html, by a "fix"_fix.html, or by an atom-style "variable"_variable.html. The output of this fix can be used as input to other output commands. Computes that generate values to output :h5,link(compute) Every "compute"_compute.html in LAMMPS produces either global or per-atom or local values. The values can be scalars or vectors or arrays of data. These values can be output using the other commands described in this section. The doc page for each compute command describes what it produces. Computes that produce per-atom or local values have the word "atom" or "local" in their style name. Computes without the word "atom" or "local" produce global values. Fixes that generate values to output :h5,link(fix) Some "fixes"_fix.html in LAMMPS produces either global or per-atom or local values which can be accessed by other commands. The values can be scalars or vectors or arrays of data. These values can be output using the other commands described in this section. The doc page for each fix command tells whether it produces any output quantities and describes them. Variables that generate values to output :h5,link(variable) "Variables"_variable.html defined in an input script can store one or more strings. But equal-style, vector-style, and atom-style or atomfile-style variables generate a global scalar value, global vector or values, or a per-atom vector, resepctively, when accessed. The formulas used to define these variables can contain references to the thermodynamic keywords and to global and per-atom data generated by computes, fixes, and other variables. The values generated by variables can be used as input to and thus output by the other commands described in this section. Summary table of output options and data flow between commands :h5,link(table) This table summarizes the various commands that can be used for generating output from LAMMPS. Each command produces output data of some kind and/or writes data to a file. Most of the commands can take data from other commands as input. Thus you can link many of these commands together in pipeline form, where data produced by one command is used as input to another command and eventually written to the screen or to a file. Note that to hook two commands together the output and input data types must match, e.g. global/per-atom/local data and scalar/vector/array data. Also note that, as described above, when a command takes a scalar as input, that could be an element of a vector or array. Likewise a vector input could be a column of an array. Command: Input: Output: "thermo_style custom"_thermo_style.html: global scalars: screen, log file: "dump custom"_dump.html: per-atom vectors: dump file: "dump local"_dump.html: local vectors: dump file: "fix print"_fix_print.html: global scalar from variable: screen, file: "print"_print.html: global scalar from variable: screen: "computes"_compute.html: N/A: global/per-atom/local scalar/vector/array: "fixes"_fix.html: N/A: global/per-atom/local scalar/vector/array: "variables"_variable.html: global scalars and vectors, per-atom vectors: global scalar and vector, per-atom vector: "compute reduce"_compute_reduce.html: per-atom/local vectors: global scalar/vector: "compute slice"_compute_slice.html: global vectors/arrays: global vector/array: "compute property/atom"_compute_property_atom.html: per-atom vectors: per-atom vector/array: "compute property/local"_compute_property_local.html: local vectors: local vector/array: "fix vector"_fix_vector.html: global scalars: global vector: "fix ave/atom"_fix_ave_atom.html: per-atom vectors: per-atom vector/array: "fix ave/time"_fix_ave_time.html: global scalars/vectors: global scalar/vector/array, file: "fix ave/chunk"_fix_ave_chunk.html: per-atom vectors: global array, file: "fix ave/histo"_fix_ave_histo.html: global/per-atom/local scalars and vectors: global array, file: "fix ave/correlate"_fix_ave_correlate.html: global scalars: global array, file: "fix store/state"_fix_store_state.html: per-atom vectors: per-atom vector/array :tb(c=3,s=:) :line 6.16 Thermostatting, barostatting, and computing temperature :link(howto_16),h4 Thermostatting means controlling the temperature of particles in an MD simulation. Barostatting means controlling the pressure. Since the pressure includes a kinetic component due to particle velocities, both these operations require calculation of the temperature. Typically a target temperature (T) and/or pressure (P) is specified by the user, and the thermostat or barostat attempts to equilibrate the system to the requested T and/or P. Temperature is computed as kinetic energy divided by some number of degrees of freedom (and the Boltzmann constant). Since kinetic energy is a function of particle velocity, there is often a need to distinguish between a particle's advection velocity (due to some aggregate motiion of particles) and its thermal velocity. The sum of the two is the particle's total velocity, but the latter is often what is wanted to compute a temperature. LAMMPS has several options for computing temperatures, any of which can be used in thermostatting and barostatting. These "compute commands"_compute.html calculate temperature, and the "compute pressure"_compute_pressure.html command calculates pressure. "compute temp"_compute_temp.html "compute temp/sphere"_compute_temp_sphere.html "compute temp/asphere"_compute_temp_asphere.html "compute temp/com"_compute_temp_com.html "compute temp/deform"_compute_temp_deform.html "compute temp/partial"_compute_temp_partial.html "compute temp/profile"_compute_temp_profile.html "compute temp/ramp"_compute_temp_ramp.html "compute temp/region"_compute_temp_region.html :ul All but the first 3 calculate velocity biases directly (e.g. advection velocities) that are removed when computing the thermal temperature. "Compute temp/sphere"_compute_temp_sphere.html and "compute temp/asphere"_compute_temp_asphere.html compute kinetic energy for finite-size particles that includes rotational degrees of freedom. They both allow for velocity biases indirectly, via an optional extra argument, another temperature compute that subtracts a velocity bias. This allows the translational velocity of spherical or aspherical particles to be adjusted in prescribed ways. Thermostatting in LAMMPS is performed by "fixes"_fix.html, or in one case by a pair style. Several thermostatting fixes are available: Nose-Hoover (nvt), Berendsen, CSVR, Langevin, and direct rescaling (temp/rescale). Dissipative particle dynamics (DPD) thermostatting can be invoked via the {dpd/tstat} pair style: "fix nvt"_fix_nh.html "fix nvt/sphere"_fix_nvt_sphere.html "fix nvt/asphere"_fix_nvt_asphere.html "fix nvt/sllod"_fix_nvt_sllod.html "fix temp/berendsen"_fix_temp_berendsen.html "fix temp/csvr"_fix_temp_csvr.html "fix langevin"_fix_langevin.html "fix temp/rescale"_fix_temp_rescale.html "pair_style dpd/tstat"_pair_dpd.html :ul "Fix nvt"_fix_nh.html only thermostats the translational velocity of particles. "Fix nvt/sllod"_fix_nvt_sllod.html also does this, except that it subtracts out a velocity bias due to a deforming box and integrates the SLLOD equations of motion. See the "NEMD simulations"_#howto_13 section of this page for further details. "Fix nvt/sphere"_fix_nvt_sphere.html and "fix nvt/asphere"_fix_nvt_asphere.html thermostat not only translation velocities but also rotational velocities for spherical and aspherical particles. DPD thermostatting alters pairwise interactions in a manner analagous to the per-particle thermostatting of "fix langevin"_fix_langevin.html. Any of the thermostatting fixes can use temperature computes that remove bias which has two effects. First, the current calculated temperature, which is compared to the requested target temperature, is caluclated with the velocity bias removed. Second, the thermostat adjusts only the thermal temperature component of the particle's velocities, which are the velocities with the bias removed. The removed bias is then added back to the adjusted velocities. See the doc pages for the individual fixes and for the "fix_modify"_fix_modify.html command for instructions on how to assign a temperature compute to a thermostatting fix. For example, you can apply a thermostat to only the x and z components of velocity by using it in conjunction with "compute temp/partial"_compute_temp_partial.html. Of you could thermostat only the thermal temperature of a streaming flow of particles without affecting the streaming velocity, by using "compute temp/profile"_compute_temp_profile.html. NOTE: Only the nvt fixes perform time integration, meaning they update the velocities and positions of particles due to forces and velocities respectively. The other thermostat fixes only adjust velocities; they do NOT perform time integration updates. Thus they should be used in conjunction with a constant NVE integration fix such as these: "fix nve"_fix_nve.html "fix nve/sphere"_fix_nve_sphere.html "fix nve/asphere"_fix_nve_asphere.html :ul Barostatting in LAMMPS is also performed by "fixes"_fix.html. Two barosttating methods are currently available: Nose-Hoover (npt and nph) and Berendsen: "fix npt"_fix_nh.html "fix npt/sphere"_fix_npt_sphere.html "fix npt/asphere"_fix_npt_asphere.html "fix nph"_fix_nh.html "fix press/berendsen"_fix_press_berendsen.html :ul The "fix npt"_fix_nh.html commands include a Nose-Hoover thermostat and barostat. "Fix nph"_fix_nh.html is just a Nose/Hoover barostat; it does no thermostatting. Both "fix nph"_fix_nh.html and "fix press/bernendsen"_fix_press_berendsen.html can be used in conjunction with any of the thermostatting fixes. As with the thermostats, "fix npt"_fix_nh.html and "fix nph"_fix_nh.html only use translational motion of the particles in computing T and P and performing thermo/barostatting. "Fix npt/sphere"_fix_npt_sphere.html and "fix npt/asphere"_fix_npt_asphere.html thermo/barostat using not only translation velocities but also rotational velocities for spherical and aspherical particles. All of the barostatting fixes use the "compute pressure"_compute_pressure.html compute to calculate a current pressure. By default, this compute is created with a simple "compute temp"_compute_temp.html (see the last argument of the "compute pressure"_compute_pressure.html command), which is used to calculated the kinetic component of the pressure. The barostatting fixes can also use temperature computes that remove bias for the purpose of computing the kinetic component which contributes to the current pressure. See the doc pages for the individual fixes and for the "fix_modify"_fix_modify.html command for instructions on how to assign a temperature or pressure compute to a barostatting fix. NOTE: As with the thermostats, the Nose/Hoover methods ("fix npt"_fix_nh.html and "fix nph"_fix_nh.html) perform time integration. "Fix press/berendsen"_fix_press_berendsen.html does NOT, so it should be used with one of the constant NVE fixes or with one of the NVT fixes. Finally, thermodynamic output, which can be setup via the "thermo_style"_thermo_style.html command, often includes temperature and pressure values. As explained on the doc page for the "thermo_style"_thermo_style.html command, the default T and P are setup by the thermo command itself. They are NOT the ones associated with any thermostatting or barostatting fix you have defined or with any compute that calculates a temperature or pressure. Thus if you want to view these values of T and P, you need to specify them explicitly via a "thermo_style custom"_thermo_style.html command. Or you can use the "thermo_modify"_thermo_modify.html command to re-define what temperature or pressure compute is used for default thermodynamic output. :line 6.17 Walls :link(howto_17),h4 Walls in an MD simulation are typically used to bound particle motion, i.e. to serve as a boundary condition. Walls in LAMMPS can be of rough (made of particles) or idealized surfaces. Ideal walls can be smooth, generating forces only in the normal direction, or frictional, generating forces also in the tangential direction. Rough walls, built of particles, can be created in various ways. The particles themselves can be generated like any other particle, via the "lattice"_lattice.html and "create_atoms"_create_atoms.html commands, or read in via the "read_data"_read_data.html command. Their motion can be constrained by many different commands, so that they do not move at all, move together as a group at constant velocity or in response to a net force acting on them, move in a prescribed fashion (e.g. rotate around a point), etc. Note that if a time integration fix like "fix nve"_fix_nve.html or "fix nvt"_fix_nh.html is not used with the group that contains wall particles, their positions and velocities will not be updated. "fix aveforce"_fix_aveforce.html - set force on particles to average value, so they move together "fix setforce"_fix_setforce.html - set force on particles to a value, e.g. 0.0 "fix freeze"_fix_freeze.html - freeze particles for use as granular walls "fix nve/noforce"_fix_nve_noforce.html - advect particles by their velocity, but without force "fix move"_fix_move.html - prescribe motion of particles by a linear velocity, oscillation, rotation, variable :ul The "fix move"_fix_move.html command offers the most generality, since the motion of individual particles can be specified with "variable"_variable.html formula which depends on time and/or the particle position. For rough walls, it may be useful to turn off pairwise interactions between wall particles via the "neigh_modify exclude"_neigh_modify.html command. Rough walls can also be created by specifying frozen particles that do not move and do not interact with mobile particles, and then tethering other particles to the fixed particles, via a "bond"_bond_style.html. The bonded particles do interact with other mobile particles. Idealized walls can be specified via several fix commands. "Fix wall/gran"_fix_wall_gran.html creates frictional walls for use with granular particles; all the other commands create smooth walls. "fix wall/reflect"_fix_wall_reflect.html - reflective flat walls "fix wall/lj93"_fix_wall.html - flat walls, with Lennard-Jones 9/3 potential "fix wall/lj126"_fix_wall.html - flat walls, with Lennard-Jones 12/6 potential "fix wall/colloid"_fix_wall.html - flat walls, with "pair_style colloid"_pair_colloid.html potential "fix wall/harmonic"_fix_wall.html - flat walls, with repulsive harmonic spring potential "fix wall/region"_fix_wall_region.html - use region surface as wall "fix wall/gran"_fix_wall_gran.html - flat or curved walls with "pair_style granular"_pair_gran.html potential :ul The {lj93}, {lj126}, {colloid}, and {harmonic} styles all allow the flat walls to move with a constant velocity, or oscillate in time. The "fix wall/region"_fix_wall_region.html command offers the most generality, since the region surface is treated as a wall, and the geometry of the region can be a simple primitive volume (e.g. a sphere, or cube, or plane), or a complex volume made from the union and intersection of primitive volumes. "Regions"_region.html can also specify a volume "interior" or "exterior" to the specified primitive shape or {union} or {intersection}. "Regions"_region.html can also be "dynamic" meaning they move with constant velocity, oscillate, or rotate. The only frictional idealized walls currently in LAMMPS are flat or curved surfaces specified by the "fix wall/gran"_fix_wall_gran.html command. At some point we plan to allow regoin surfaces to be used as frictional walls, as well as triangulated surfaces. :line 6.18 Elastic constants :link(howto_18),h4 Elastic constants characterize the stiffness of a material. The formal definition is provided by the linear relation that holds between the stress and strain tensors in the limit of infinitesimal deformation. In tensor notation, this is expressed as s_ij = C_ijkl * e_kl, where the repeated indices imply summation. s_ij are the elements of the symmetric stress tensor. e_kl are the elements of the symmetric strain tensor. C_ijkl are the elements of the fourth rank tensor of elastic constants. In three dimensions, this tensor has 3^4=81 elements. Using Voigt notation, the tensor can be written as a 6x6 matrix, where C_ij is now the derivative of s_i w.r.t. e_j. Because s_i is itself a derivative w.r.t. e_i, it follows that C_ij is also symmetric, with at most 7*6/2 = 21 distinct elements. At zero temperature, it is easy to estimate these derivatives by deforming the simulation box in one of the six directions using the "change_box"_change_box.html command and measuring the change in the stress tensor. A general-purpose script that does this is given in the examples/elastic directory described in "this section"_Section_example.html. Calculating elastic constants at finite temperature is more challenging, because it is necessary to run a simulation that perfoms time averages of differential properties. One way to do this is to measure the change in average stress tensor in an NVT simulations when the cell volume undergoes a finite deformation. In order to balance the systematic and statistical errors in this method, the magnitude of the deformation must be chosen judiciously, and care must be taken to fully equilibrate the deformed cell before sampling the stress tensor. Another approach is to sample the triclinic cell fluctuations that occur in an NPT simulation. This method can also be slow to converge and requires careful post-processing "(Shinoda)"_#Shinoda :line 6.19 Library interface to LAMMPS :link(howto_19),h4 As described in "Section 2.5"_Section_start.html#start_5, LAMMPS can be built as a library, so that it can be called by another code, used in a "coupled manner"_Section_howto.html#howto_10 with other codes, or driven through a "Python interface"_Section_python.html. All of these methodologies use a C-style interface to LAMMPS that is provided in the files src/library.cpp and src/library.h. The functions therein have a C-style argument list, but contain C++ code you could write yourself in a C++ application that was invoking LAMMPS directly. The C++ code in the functions illustrates how to invoke internal LAMMPS operations. Note that LAMMPS classes are defined within a LAMMPS namespace (LAMMPS_NS) if you use them from another C++ application. Library.cpp contains these 5 basic functions: void lammps_open(int, char **, MPI_Comm, void **) void lammps_close(void *) int lammps_version(void *) void lammps_file(void *, char *) char *lammps_command(void *, char *) :pre The lammps_open() function is used to initialize LAMMPS, passing in a list of strings as if they were "command-line arguments"_Section_start.html#start_7 when LAMMPS is run in stand-alone mode from the command line, and a MPI communicator for LAMMPS to run under. It returns a ptr to the LAMMPS object that is created, and which is used in subsequent library calls. The lammps_open() function can be called multiple times, to create multiple instances of LAMMPS. LAMMPS will run on the set of processors in the communicator. This means the calling code can run LAMMPS on all or a subset of processors. For example, a wrapper script might decide to alternate between LAMMPS and another code, allowing them both to run on all the processors. Or it might allocate half the processors to LAMMPS and half to the other code and run both codes simultaneously before syncing them up periodically. Or it might instantiate multiple instances of LAMMPS to perform different calculations. The lammps_close() function is used to shut down an instance of LAMMPS and free all its memory. The lammps_version() function can be used to determined the specific version of the underlying LAMMPS code. This is particularly useful when loading LAMMPS as a shared library via dlopen(). The code using the library interface can than use this information to adapt to changes to the LAMMPS command syntax between versions. The returned LAMMPS version code is an integer (e.g. 2 Sep 2015 results in 20150902) that grows with every new LAMMPS version. The lammps_file() and lammps_command() functions are used to pass a file or string to LAMMPS as if it were an input script or single command in an input script. Thus the calling code can read or generate a series of LAMMPS commands one line at a time and pass it thru the library interface to setup a problem and then run it, interleaving the lammps_command() calls with other calls to extract information from LAMMPS, perform its own operations, or call another code's library. Other useful functions are also included in library.cpp. For example: void *lammps_extract_global(void *, char *) void *lammps_extract_atom(void *, char *) 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_get_coords(void *, double *) void lammps_put_coords(void *, double *) :pre These can extract various global or per-atom quantities from LAMMPS as well as values calculated by a compute, fix, or variable. The "set_variable" function can set an existing string-style variable to a new value, so that subsequent LAMMPS commands can access the variable. The "get" and "put" operations can retrieve and reset atom coordinates. See the library.cpp file and its associated header file library.h for details. The key idea of the library interface is that you can write any functions you wish to define how your code talks to LAMMPS and add them to src/library.cpp and src/library.h, as well as to the "Python interface"_Section_python.html. The routines you add can access or change any LAMMPS data you wish. The examples/COUPLE and python directories have example C++ and C and Python codes which show how a driver code can link to LAMMPS as a library, run LAMMPS on a subset of processors, grab data from LAMMPS, change it, and put it back into LAMMPS. :line 6.20 Calculating thermal conductivity :link(howto_20),h4 The thermal conductivity kappa of a material can be measured in at least 4 ways using various options in LAMMPS. See the examples/KAPPA directory for scripts that implement the 4 methods discussed here for a simple Lennard-Jones fluid model. Also, see "this section"_Section_howto.html#howto_21 of the manual for an analogous discussion for viscosity. The thermal conducitivity tensor kappa is a measure of the propensity of a material to transmit heat energy in a diffusive manner as given by Fourier's law J = -kappa grad(T) where J is the heat flux in units of energy per area per time and grad(T) is the spatial gradient of temperature. The thermal conductivity thus has units of energy per distance per time per degree K and is often approximated as an isotropic quantity, i.e. as a scalar. The first method is to setup two thermostatted regions at opposite ends of a simulation box, or one in the middle and one at the end of a periodic box. By holding the two regions at different temperatures with a "thermostatting fix"_Section_howto.html#howto_13, the energy added to the hot region should equal the energy subtracted from the cold region and be proportional to the heat flux moving between the regions. See the papers by "Ikeshoji and Hafskjold"_#howto-Ikeshoji and "Wirnsberger et al"_#howto-Wirnsberger for details of this idea. Note that thermostatting fixes such as "fix nvt"_fix_nh.html, "fix langevin"_fix_langevin.html, and "fix temp/rescale"_fix_temp_rescale.html store the cumulative energy they add/subtract. Alternatively, as a second method, the "fix heat"_fix_heat.html or "fix ehex"_fix_ehex.html commands can be used in place of thermostats on each of two regions to add/subtract specified amounts of energy to both regions. In both cases, the resulting temperatures of the two regions can be monitored with the "compute temp/region" command and the temperature profile of the intermediate region can be monitored with the "fix ave/chunk"_fix_ave_chunk.html and "compute ke/atom"_compute_ke_atom.html commands. The third method is to perform a reverse non-equilibrium MD simulation using the "fix thermal/conductivity"_fix_thermal_conductivity.html command which implements the rNEMD algorithm of Muller-Plathe. Kinetic energy is swapped between atoms in two different layers of the simulation box. This induces a temperature gradient between the two layers which can be monitored with the "fix ave/chunk"_fix_ave_chunk.html and "compute ke/atom"_compute_ke_atom.html commands. The fix tallies the cumulative energy transfer that it performs. See the "fix thermal/conductivity"_fix_thermal_conductivity.html command for details. The fourth method is based on the Green-Kubo (GK) formula which relates the ensemble average of the auto-correlation of the heat flux to kappa. The heat flux can be calculated from the fluctuations of per-atom potential and kinetic energies and per-atom stress tensor in a steady-state equilibrated simulation. This is in contrast to the two preceding non-equilibrium methods, where energy flows continuously between hot and cold regions of the simulation box. The "compute heat/flux"_compute_heat_flux.html command can calculate the needed heat flux and describes how to implement the Green_Kubo formalism using additional LAMMPS commands, such as the "fix ave/correlate"_fix_ave_correlate.html command to calculate the needed auto-correlation. See the doc page for the "compute heat/flux"_compute_heat_flux.html command for an example input script that calculates the thermal conductivity of solid Ar via the GK formalism. :line 6.21 Calculating viscosity :link(howto_21),h4 The shear viscosity eta of a fluid can be measured in at least 5 ways using various options in LAMMPS. See the examples/VISCOSITY directory for scripts that implement the 5 methods discussed here for a simple Lennard-Jones fluid model. Also, see "this section"_Section_howto.html#howto_20 of the manual for an analogous discussion for thermal conductivity. Eta is a measure of the propensity of a fluid to transmit momentum in a direction perpendicular to the direction of velocity or momentum flow. Alternatively it is the resistance the fluid has to being sheared. It is given by J = -eta grad(Vstream) where J is the momentum flux in units of momentum per area per time. and grad(Vstream) is the spatial gradient of the velocity of the fluid moving in another direction, normal to the area through which the momentum flows. Viscosity thus has units of pressure-time. The first method is to perform a non-equlibrium MD (NEMD) simulation by shearing the simulation box via the "fix deform"_fix_deform.html command, and using the "fix nvt/sllod"_fix_nvt_sllod.html command to thermostat the fluid via the SLLOD equations of motion. Alternatively, as a second method, one or more moving walls can be used to shear the fluid in between them, again with some kind of thermostat that modifies only the thermal (non-shearing) components of velocity to prevent the fluid from heating up. In both cases, the velocity profile setup in the fluid by this procedure can be monitored by the "fix ave/chunk"_fix_ave_chunk.html command, which determines grad(Vstream) in the equation above. E.g. the derivative in the y-direction of the Vx component of fluid motion or grad(Vstream) = dVx/dy. The Pxy off-diagonal component of the pressure or stress tensor, as calculated by the "compute pressure"_compute_pressure.html command, can also be monitored, which is the J term in the equation above. See "this section"_Section_howto.html#howto_13 of the manual for details on NEMD simulations. The third method is to perform a reverse non-equilibrium MD simulation using the "fix viscosity"_fix_viscosity.html command which implements the rNEMD algorithm of Muller-Plathe. Momentum in one dimension is swapped between atoms in two different layers of the simulation box in a different dimension. This induces a velocity gradient which can be monitored with the "fix ave/chunk"_fix_ave_chunk.html command. The fix tallies the cummulative momentum transfer that it performs. See the "fix viscosity"_fix_viscosity.html command for details. The fourth method is based on the Green-Kubo (GK) formula which relates the ensemble average of the auto-correlation of the stress/pressure tensor to eta. This can be done in a fully equilibrated simulation which is in contrast to the two preceding non-equilibrium methods, where momentum flows continuously through the simulation box. Here is an example input script that calculates the viscosity of liquid Ar via the GK formalism: # Sample LAMMPS input script for viscosity of liquid Ar :pre units real variable T equal 86.4956 variable V equal vol variable dt equal 4.0 variable p equal 400 # correlation length variable s equal 5 # sample interval variable d equal $p*$s # dump interval :pre # convert from LAMMPS real units to SI :pre variable kB equal 1.3806504e-23 # \[J/K/] Boltzmann variable atm2Pa equal 101325.0 variable A2m equal 1.0e-10 variable fs2s equal 1.0e-15 variable convert equal $\{atm2Pa\}*$\{atm2Pa\}*$\{fs2s\}*$\{A2m\}*$\{A2m\}*$\{A2m\} :pre # setup problem :pre dimension 3 boundary p p p lattice fcc 5.376 orient x 1 0 0 orient y 0 1 0 orient z 0 0 1 region box block 0 4 0 4 0 4 create_box 1 box create_atoms 1 box -mass 1 39.948 +mass 1 39.948 pair_style lj/cut 13.0 pair_coeff * * 0.2381 3.405 timestep $\{dt\} -thermo $d :pre +thermo $d :pre # equilibration and thermalization :pre velocity all create $T 102486 mom yes rot yes dist gaussian fix NVT all nvt temp $T $T 10 drag 0.2 run 8000 :pre # viscosity calculation, switch to NVE if desired :pre #unfix NVT #fix NVE all nve :pre reset_timestep 0 variable pxy equal pxy variable pxz equal pxz variable pyz equal pyz fix SS all ave/correlate $s $p $d & v_pxy v_pxz v_pyz type auto file S0St.dat ave running variable scale equal $\{convert\}/($\{kB\}*$T)*$V*$s*$\{dt\} variable v11 equal trap(f_SS\[3\])*$\{scale\} variable v22 equal trap(f_SS\[4\])*$\{scale\} variable v33 equal trap(f_SS\[5\])*$\{scale\} thermo_style custom step temp press v_pxy v_pxz v_pyz v_v11 v_v22 v_v33 run 100000 variable v equal (v_v11+v_v22+v_v33)/3.0 variable ndens equal count(all)/vol print "average viscosity: $v \[Pa.s\] @ $T K, $\{ndens\} /A^3" :pre The fifth method is related to the above Green-Kubo method, but uses the Einstein formulation, analogous to the Einstein mean-square-displacement formulation for self-diffusivity. The time-integrated momentum fluxes play the role of Cartesian coordinates, whose mean-square displacement increases linearly with time at sufficiently long times. :line 6.22 Calculating a diffusion coefficient :link(howto_22),h4 The diffusion coefficient D of a material can be measured in at least 2 ways using various options in LAMMPS. See the examples/DIFFUSE directory for scripts that implement the 2 methods discussed here for a simple Lennard-Jones fluid model. The first method is to measure the mean-squared displacement (MSD) of the system, via the "compute msd"_compute_msd.html command. The slope of the MSD versus time is proportional to the diffusion coefficient. The instantaneous MSD values can be accumulated in a vector via the "fix vector"_fix_vector.html command, and a line fit to the vector to compute its slope via the "variable slope"_variable.html function, and thus extract D. The second method is to measure the velocity auto-correlation function (VACF) of the system, via the "compute vacf"_compute_vacf.html command. The time-integral of the VACF is proportional to the diffusion coefficient. The instantaneous VACF values can be accumulated in a vector via the "fix vector"_fix_vector.html command, and time integrated via the "variable trap"_variable.html function, and thus extract D. :line 6.23 Using chunks to calculate system properties :link(howto_23),h4 In LAMMS, "chunks" are collections of atoms, as defined by the "compute chunk/atom"_compute_chunk_atom.html command, which assigns each atom to a chunk ID (or to no chunk at all). The number of chunks and the assignment of chunk IDs to atoms can be static or change over time. Examples of "chunks" are molecules or spatial bins or atoms with similar values (e.g. coordination number or potential energy). The per-atom chunk IDs can be used as input to two other kinds of commands, to calculate various properties of a system: "fix ave/chunk"_fix_ave_chunk.html any of the "compute */chunk"_compute.html commands :ul Here, each of the 3 kinds of chunk-related commands is briefly overviewed. Then some examples are given of how to compute different properties with chunk commands. Compute chunk/atom command: :h5 This compute can assign atoms to chunks of various styles. Only atoms in the specified group and optional specified region are assigned to a chunk. Here are some possible chunk definitions: atoms in same molecule | chunk ID = molecule ID | atoms of same atom type | chunk ID = atom type | all atoms with same atom property (charge, radius, etc) | chunk ID = output of compute property/atom | atoms in same cluster | chunk ID = output of "compute cluster/atom"_compute_cluster_atom.html command | atoms in same spatial bin | chunk ID = bin ID | atoms in same rigid body | chunk ID = molecule ID used to define rigid bodies | atoms with similar potential energy | chunk ID = output of "compute pe/atom"_compute_pe_atom.html | atoms with same local defect structure | chunk ID = output of "compute centro/atom"_compute_centro_atom.html or "compute coord/atom"_compute_coord_atom.html command :tb(s=|,c=2) Note that chunk IDs are integer values, so for atom properties or computes that produce a floating point value, they will be truncated to an integer. You could also use the compute in a variable that scales the floating point value to spread it across multiple intergers. Spatial bins can be of various kinds, e.g. 1d bins = slabs, 2d bins = pencils, 3d bins = boxes, spherical bins, cylindrical bins. This compute also calculates the number of chunks {Nchunk}, which is used by other commands to tally per-chunk data. {Nchunk} can be a static value or change over time (e.g. the number of clusters). The chunk ID for an individual atom can also be static (e.g. a molecule ID), or dynamic (e.g. what spatial bin an atom is in as it moves). Note that this compute allows the per-atom output of other "computes"_compute.html, "fixes"_fix.html, and "variables"_variable.html to be used to define chunk IDs for each atom. This means you can write your own compute or fix to output a per-atom quantity to use as chunk ID. See "Section 10"_Section_modify.html of the documentation for how to do this. You can also define a "per-atom variable"_variable.html in the input script that uses a formula to generate a chunk ID for each atom. Fix ave/chunk command: :h5 This fix takes the ID of a "compute chunk/atom"_compute_chunk_atom.html command as input. For each chunk, it then sums one or more specified per-atom values over the atoms in each chunk. The per-atom values can be any atom property, such as velocity, force, charge, potential energy, kinetic energy, stress, etc. Additional keywords are defined for per-chunk properties like density and temperature. More generally any per-atom value generated by other "computes"_compute.html, "fixes"_fix.html, and "per-atom variables"_variable.html, can be summed over atoms in each chunk. Similar to other averaging fixes, this fix allows the summed per-chunk values to be time-averaged in various ways, and output to a file. The fix produces a global array as output with one row of values per chunk. Compute */chunk commands: :h5 Currently the following computes operate on chunks of atoms to produce per-chunk values. "compute com/chunk"_compute_com_chunk.html "compute gyration/chunk"_compute_gyration_chunk.html "compute inertia/chunk"_compute_inertia_chunk.html "compute msd/chunk"_compute_msd_chunk.html "compute property/chunk"_compute_property_chunk.html "compute temp/chunk"_compute_temp_chunk.html "compute torque/chunk"_compute_vcm_chunk.html "compute vcm/chunk"_compute_vcm_chunk.html :ul They each take the ID of a "compute chunk/atom"_compute_chunk_atom.html command as input. As their names indicate, they calculate the center-of-mass, radius of gyration, moments of inertia, mean-squared displacement, temperature, torque, and velocity of center-of-mass for each chunk of atoms. The "compute property/chunk"_compute_property_chunk.html command can tally the count of atoms in each chunk and extract other per-chunk properties. The reason these various calculations are not part of the "fix ave/chunk command"_fix_ave_chunk.html, is that each requires a more complicated operation than simply summing and averaging over per-atom values in each chunk. For example, many of them require calculation of a center of mass, which requires summing mass*position over the atoms and then dividing by summed mass. All of these computes produce a global vector or global array as output, wih one or more values per chunk. They can be used in various ways: As input to the "fix ave/time"_fix_ave_time.html command, which can write the values to a file and optionally time average them. :ulb,l As input to the "fix ave/histo"_fix_ave_histo.html command to histogram values across chunks. E.g. a histogram of cluster sizes or molecule diffusion rates. :l As input to special functions of "equal-style variables"_variable.html, like sum() and max(). E.g. to find the largest cluster or fastest diffusing molecule. :l :ule Example calculations with chunks :h5 Here are eaxmples using chunk commands to calculate various properties: (1) Average velocity in each of 1000 2d spatial bins: compute cc1 all chunk/atom bin/2d x 0.0 0.1 y lower 0.01 units reduced fix 1 all ave/chunk 100 10 1000 cc1 vx vy file tmp.out :pre (2) Temperature in each spatial bin, after subtracting a flow velocity: compute cc1 all chunk/atom bin/2d x 0.0 0.1 y lower 0.1 units reduced compute vbias all temp/profile 1 0 0 y 10 fix 1 all ave/chunk 100 10 1000 cc1 temp bias vbias file tmp.out :pre (3) Center of mass of each molecule: compute cc1 all chunk/atom molecule compute myChunk all com/chunk cc1 fix 1 all ave/time 100 1 100 c_myChunk\[*\] file tmp.out mode vector :pre (4) Total force on each molecule and ave/max across all molecules: compute cc1 all chunk/atom molecule fix 1 all ave/chunk 1000 1 1000 cc1 fx fy fz file tmp.out variable xave equal ave(f_1\[2\]) variable xmax equal max(f_1\[2\]) thermo 1000 thermo_style custom step temp v_xave v_xmax :pre (5) Histogram of cluster sizes: compute cluster all cluster/atom 1.0 compute cc1 all chunk/atom c_cluster compress yes compute size all property/chunk cc1 count fix 1 all ave/histo 100 1 100 0 20 20 c_size mode vector ave running beyond ignore file tmp.histo :pre :line 6.24 Setting parameters for the "kspace_style pppm/disp"_kspace_style.html command :link(howto_24),h4 The PPPM method computes interactions by splitting the pair potential into two parts, one of which is computed in a normal pairwise fashion, the so-called real-space part, and one of which is computed using the Fourier transform, the so called reciprocal-space or kspace part. For both parts, the potential is not computed exactly but is approximated. Thus, there is an error in both parts of the computation, the real-space and the kspace error. The just mentioned facts are true both for the PPPM for Coulomb as well as dispersion interactions. The deciding difference - and also the reason why the parameters for pppm/disp have to be selected with more care - is the impact of the errors on the results: The kspace error of the PPPM for Coulomb and dispersion interaction and the real-space error of the PPPM for Coulomb interaction have the character of noise. In contrast, the real-space error of the PPPM for dispersion has a clear physical interpretation: the underprediction of cohesion. As a consequence, the real-space error has a much stronger effect than the kspace error on simulation results for pppm/disp. Parameters must thus be chosen in a way that this error is much smaller than the kspace error. When using pppm/disp and not making any specifications on the PPPM parameters via the kspace modify command, parameters will be tuned such that the real-space error and the kspace error are equal. This will result in simulations that are either inaccurate or slow, both of which is not desirable. For selecting parameters for the pppm/disp that provide fast and accurate simulations, there are two approaches, which both have their up- and downsides. The first approach is to set desired real-space an kspace accuracies via the {kspace_modify force/disp/real} and {kspace_modify force/disp/kspace} commands. Note that the accuracies have to be specified in force units and are thus dependend on the chosen unit settings. For real units, 0.0001 and 0.002 seem to provide reasonable accurate and efficient computations for the real-space and kspace accuracies. 0.002 and 0.05 work well for most systems using lj units. PPPM parameters will be generated based on the desired accuracies. The upside of this approach is that it usually provides a good set of parameters and will work for both the {kspace_modify diff ad} and {kspace_modify diff ik} options. The downside of the method is that setting the PPPM parameters will take some time during the initialization of the simulation. The second approach is to set the parameters for the pppm/disp explicitly using the {kspace_modify mesh/disp}, {kspace_modify order/disp}, and {kspace_modify gewald/disp} commands. This approach requires a more experienced user who understands well the impact of the choice of parameters on the simulation accuracy and performance. This approach provides a fast initialization of the simulation. However, it is sensitive to errors: A combination of parameters that will perform well for one system might result in far-from-optimal conditions for other simulations. For example, parametes that provide accurate and fast computations for all-atomistic force fields can provide insufficient accuracy or united-atomistic force fields (which is related to that the latter typically have larger dispersion coefficients). To avoid inaccurate or inefficient simulations, the pppm/disp stops simulations with an error message if no action is taken to control the PPPM parameters. If the automatic parameter generation is desired and real-space and kspace accuracies are desired to be equal, this error message can be suppressed using the {kspace_modify disp/auto yes} command. A reasonable approach that combines the upsides of both methods is to make the first run using the {kspace_modify force/disp/real} and {kspace_modify force/disp/kspace} commands, write down the PPPM parameters from the outut, and specify these parameters using the second approach in subsequent runs (which have the same composition, force field, and approximately the same volume). Concerning the performance of the pppm/disp there are two more things to consider. The first is that when using the pppm/disp, the cutoff parameter does no longer affect the accuracy of the simulation (subject to that gewald/disp is adjusted when changing the cutoff). The performance can thus be increased by examining different values for the cutoff parameter. A lower bound for the cutoff is only set by the truncation error of the repulsive term of pair potentials. The second is that the mixing rule of the pair style has an impact on the computation time when using the pppm/disp. Fastest computations are achieved when using the geometric mixing rule. Using the arithmetic mixing rule substantially increases the computational cost. The computational overhead can be reduced using the {kspace_modify mix/disp geom} and {kspace_modify splittol} commands. The first command simply enforces geometric mixing of the dispersion coeffiecients in kspace computations. This introduces some error in the computations but will also significantly speed-up the simulations. The second keyword sets the accuracy with which the dispersion coefficients are approximated using a matrix factorization approach. This may result in better accuracy then using the first command, but will usually also not provide an equally good increase of efficiency. Finally, pppm/disp can also be used when no mixing rules apply. This can be achieved using the {kspace_modify mix/disp none} command. Note that the code does not check automatically whether any mixing rule is fulfilled. If mixing rules do not apply, the user will have to specify this command explicitly. :line 6.25 Polarizable models :link(howto_25),h4 In polarizable force fields the charge distributions in molecules and materials respond to their electrostatic environements. Polarizable systems can be simulated in LAMMPS using three methods: the fluctuating charge method, implemented in the "QEQ"_fix_qeq.html package, :ulb,l the adiabatic core-shell method, implemented in the "CORESHELL"_#howto_26 package, :l the thermalized Drude dipole method, implemented in the "USER-DRUDE"_#howto_27 package. :l :ule The fluctuating charge method calculates instantaneous charges on interacting atoms based on the electronegativity equalization principle. It is implemented in the "fix qeq"_fix_qeq.html which is available in several variants. It is a relatively efficient technique since no additional particles are introduced. This method allows for charge transfer between molecules or atom groups. However, because the charges are located at the interaction sites, off-plane components of polarization cannot be represented in planar molecules or atom groups. The two other methods share the same basic idea: polarizable atoms are split into one core atom and one satellite particle (called shell or Drude particle) attached to it by a harmonic spring. Both atoms bear a charge and they represent collectively an induced electric dipole. These techniques are computationally more expensive than the QEq method because of additional particles and bonds. These two charge-on-spring methods differ in certain features, with the core-shell model being normally used for ionic/crystalline materials, whereas the so-called Drude model is normally used for molecular systems and fluid states. The core-shell model is applicable to crystalline materials where the high symmetry around each site leads to stable trajectories of the core-shell pairs. However, bonded atoms in molecules can be so close that a core would interact too strongly or even capture the Drude particle of a neighbor. The Drude dipole model is relatively more complex in order to remediate this and other issues. Specifically, the Drude model includes specific thermostating of the core-Drude pairs and short-range damping of the induced dipoles. The three polarization methods can be implemented through a self-consistent calculation of charges or induced dipoles at each timestep. In the fluctuating charge scheme this is done by the matrix inversion method in "fix qeq/point"_fix_qeq.html, but for core-shell or Drude-dipoles the relaxed-dipoles technique would require an slow iterative procedure. These self-consistent solutions yield accurate trajectories since the additional degrees of freedom representing polarization are massless. An alternative is to attribute a mass to the additional degrees of freedom and perform time integration using an extended Lagrangian technique. For the fluctuating charge scheme this is done by "fix qeq/dynamic"_fix_qeq.html, and for the charge-on-spring models by the methods outlined in the next two sections. The assignment of masses to the additional degrees of freedom can lead to unphysical trajectories if care is not exerted in choosing the parameters of the poarizable models and the simulation conditions. In the core-shell model the vibration of the shells is kept faster than the ionic vibrations to mimic the fast response of the polarizable electrons. But in molecular systems thermalizing the core-Drude pairs at temperatures comparable to the rest of the simulation leads to several problems (kinetic energy transfer, too short a timestep, etc.) In order to avoid these problems the relative motion of the Drude particles with respect to their cores is kept "cold" so the vibration of the core-Drude pairs is very slow, approaching the self-consistent regime. In both models the temperature is regulated using the velocities of the center of mass of core+shell (or Drude) pairs, but in the Drude model the actual relative core-Drude particle motion is thermostated separately as well. :line 6.26 Adiabatic core/shell model :link(howto_26),h4 The adiabatic core-shell model by "Mitchell and Finchham"_#MitchellFinchham is a simple method for adding polarizability to a system. In order to mimic the electron shell of an ion, a satellite particle is attached to it. This way the ions are split into a core and a shell where the latter is meant to react to the electrostatic environment inducing polarizability. Technically, shells are attached to the cores by a spring force f = k*r where k is a parametrized spring constant and r is the distance between the core and the shell. The charges of the core and the shell add up to the ion charge, thus q(ion) = q(core) + q(shell). This setup introduces the ion polarizability (alpha) given by alpha = q(shell)^2 / k. In a similar fashion the mass of the ion is distributed on the core and the shell with the core having the larger mass. To run this model in LAMMPS, "atom_style"_atom_style.html {full} can be used since atom charge and bonds are needed. Each kind of core/shell pair requires two atom types and a bond type. The core and shell of a core/shell pair should be bonded to each other with a harmonic bond that provides the spring force. For example, a data file for NaCl, as found in examples/coreshell, has this format: 432 atoms # core and shell atoms 216 bonds # number of core/shell springs :pre 4 atom types # 2 cores and 2 shells for Na and Cl 2 bond types :pre 0.0 24.09597 xlo xhi 0.0 24.09597 ylo yhi 0.0 24.09597 zlo zhi :pre Masses # core/shell mass ratio = 0.1 :pre 1 20.690784 # Na core 2 31.90500 # Cl core 3 2.298976 # Na shell 4 3.54500 # Cl shell :pre Atoms :pre 1 1 2 1.5005 0.00000000 0.00000000 0.00000000 # core of core/shell pair 1 2 1 4 -2.5005 0.00000000 0.00000000 0.00000000 # shell of core/shell pair 1 3 2 1 1.5056 4.01599500 4.01599500 4.01599500 # core of core/shell pair 2 4 2 3 -0.5056 4.01599500 4.01599500 4.01599500 # shell of core/shell pair 2 (...) :pre Bonds # Bond topology for spring forces :pre 1 2 1 2 # spring for core/shell pair 1 2 2 3 4 # spring for core/shell pair 2 (...) :pre Non-Coulombic (e.g. Lennard-Jones) pairwise interactions are only defined between the shells. Coulombic interactions are defined between all cores and shells. If desired, additional bonds can be specified between cores. The "special_bonds"_special_bonds.html command should be used to turn-off the Coulombic interaction within core/shell pairs, since that interaction is set by the bond spring. This is done using the "special_bonds"_special_bonds.html command with a 1-2 weight = 0.0, which is the default value. It needs to be considered whether one has to adjust the "special_bonds"_special_bonds.html weighting according to the molecular topology since the interactions of the shells are bypassed over an extra bond. Note that this core/shell implementation does not require all ions to be polarized. One can mix core/shell pairs and ions without a satellite particle if desired. Since the core/shell model permits distances of r = 0.0 between the core and shell, a pair style with a "cs" suffix needs to be used to implement a valid long-range Coulombic correction. Several such pair styles are provided in the CORESHELL package. See "this doc page"_pair_cs.html for details. All of the core/shell enabled pair styles require the use of a long-range Coulombic solver, as specified by the "kspace_style"_kspace_style.html command. Either the PPPM or Ewald solvers can be used. For the NaCL example problem, these pair style and bond style settings are used: pair_style born/coul/long/cs 20.0 20.0 pair_coeff * * 0.0 1.000 0.00 0.00 0.00 pair_coeff 3 3 487.0 0.23768 0.00 1.05 0.50 #Na-Na pair_coeff 3 4 145134.0 0.23768 0.00 6.99 8.70 #Na-Cl pair_coeff 4 4 405774.0 0.23768 0.00 72.40 145.40 #Cl-Cl :pre bond_style harmonic bond_coeff 1 63.014 0.0 bond_coeff 2 25.724 0.0 :pre When running dynamics with the adiabatic core/shell model, the following issues should be considered. Since the relative motion of the core and shell particles corresponds to the polarization, typical thermostats can alter the polarization behaviour, meaning the shell will not react freely to its electrostatic environment. This is critical during the equilibration of the system. Therefore it's typically desirable to decouple the relative motion of the core/shell pair, which is an imaginary degree of freedom, from the real physical system. To do that, the "compute temp/cs"_compute_temp_cs.html command can be used, in conjunction with any of the thermostat fixes, such as "fix nvt"_fix_nh.html or "fix langevin"_fix_langevin. This compute uses the center-of-mass velocity of the core/shell pairs to calculate a temperature, and insures that velocity is what is rescaled for thermostatting purposes. This compute also works for a system with both core/shell pairs and non-polarized ions (ions without an attached satellite particle). The "compute temp/cs"_compute_temp_cs.html command requires input of two groups, one for the core atoms, another for the shell atoms. Non-polarized ions which might also be included in the treated system should not be included into either of these groups, they are taken into account by the {group-ID} (2nd argument) of the compute. The groups can be defined using the "group {type}"_group.html command. Note that to perform thermostatting using this definition of temperature, the "fix modify temp"_fix_modify.html command should be used to assign the compute to the thermostat fix. Likewise the "thermo_modify temp"_thermo_modify.html command can be used to make this temperature be output for the overall system. For the NaCl example, this can be done as follows: group cores type 1 2 group shells type 3 4 compute CSequ all temp/cs cores shells fix thermoberendsen all temp/berendsen 1427 1427 0.4 # thermostat for the true physical system fix thermostatequ all nve # integrator as needed for the berendsen thermostat fix_modify thermoberendsen temp CSequ thermo_modify temp CSequ # output of center-of-mass derived temperature :pre If "compute temp/cs"_compute_temp_cs.html is used, the decoupled relative motion of the core and the shell should in theory be stable. However numerical fluctuation can introduce a small momentum to the system, which is noticable over long trajectories. Therefore it is recomendable to use the "fix momentum"_fix_momentum.html command in combination with "compute temp/cs"_compute_temp_cs.html when equilibrating the system to prevent any drift. When intializing the velocities of a system with core/shell pairs, it is also desirable to not introduce energy into the relative motion of the core/shell particles, but only assign a center-of-mass velocity to the pairs. This can be done by using the {bias} keyword of the "velocity create"_velocity.html command and assigning the "compute temp/cs"_compute_temp_cs.html command to the {temp} keyword of the "velocity"_velocity.html commmand, e.g. velocity all create 1427 134 bias yes temp CSequ velocity all scale 1427 temp CSequ :pre It is important to note that the polarizability of the core/shell pairs is based on their relative motion. Therefore the choice of spring force and mass ratio need to ensure much faster relative motion of the 2 atoms within the core/shell pair than their center-of-mass velocity. This allow the shells to effectively react instantaneously to the electrostatic environment. This fast movement also limits the timestep size that can be used. The primary literature of the adiabatic core/shell model suggests that the fast relative motion of the core/shell pairs only allows negligible energy transfer to the environment. Therefore it is not intended to decouple the core/shell degree of freedom from the physical system during production runs. In other words, the "compute temp/cs"_compute_temp_cs.html command should not be used during production runs and is only required during equilibration. This way one is consistent with literature (based on the code packages DL_POLY or GULP for instance). The mentioned energy transfer will typically lead to a a small drift in total energy over time. This internal energy can be monitored using the "compute chunk/atom"_compute_chunk_atom.html and "compute temp/chunk"_compute_temp_chunk.html commands. The internal kinetic energies of each core/shell pair can then be summed using the sum() special function of the "variable"_variable.html command. Or they can be time/averaged and output using the "fix ave/time"_fix_ave_time.html command. To use these commands, each core/shell pair must be defined as a "chunk". If each core/shell pair is defined as its own molecule, the molecule ID can be used to define the chunks. If cores are bonded to each other to form larger molecules, the chunks can be identified by the "fix property/atom"_fix_property_atom.html via assigning a core/shell ID to each atom using a special field in the data file read by the "read_data"_read_data.html command. This field can then be accessed by the "compute property/atom"_compute_property_atom.html command, to use as input to the "compute chunk/atom"_compute_chunk_atom.html command to define the core/shell pairs as chunks. For example, fix csinfo all property/atom i_CSID # property/atom command read_data NaCl_CS_x0.1_prop.data fix csinfo NULL CS-Info # atom property added in the data-file compute prop all property/atom i_CSID compute cs_chunk all chunk/atom c_prop compute cstherm all temp/chunk cs_chunk temp internal com yes cdof 3.0 # note the chosen degrees of freedom for the core/shell pairs fix ave_chunk all ave/time 10 1 10 c_cstherm file chunk.dump mode vector :pre The additional section in the date file would be formatted like this: CS-Info # header of additional section :pre 1 1 # column 1 = atom ID, column 2 = core/shell ID 2 1 3 2 4 2 5 3 6 3 7 4 8 4 (...) :pre :line 6.27 Drude induced dipoles :link(howto_27),h4 The thermalized Drude model, similarly to the "core-shell"_#howto_26 model, representes induced dipoles by a pair of charges (the core atom and the Drude particle) connected by a harmonic spring. The Drude model has a number of features aimed at its use in molecular systems ("Lamoureux and Roux"_#howto-Lamoureux): Thermostating of the additional degrees of freedom associated with the induced dipoles at very low temperature, in terms of the reduced coordinates of the Drude particles with respect to their cores. This makes the trajectory close to that of relaxed induced dipoles. :ulb,l Consistent definition of 1-2 to 1-4 neighbors. A core-Drude particle pair represents a single (polarizable) atom, so the special screening factors in a covalent structure should be the same for the core and the Drude particle. Drude particles have to inherit the 1-2, 1-3, 1-4 special neighbor relations from their respective cores. :l Stabilization of the interactions between induced dipoles. Drude dipoles on covalently bonded atoms interact too strongly due to the short distances, so an atom may capture the Drude particle of a neighbor, or the induced dipoles within the same molecule may align too much. To avoid this, damping at short range can be done by Thole functions (for which there are physical grounds). This Thole damping is applied to the point charges composing the induced dipole (the charge of the Drude particle and the opposite charge on the core, not to the total charge of the core atom). :l :ule A detailed tutorial covering the usage of Drude induced dipoles in LAMMPS is "available here"_tutorial_drude.html. As with the core-shell model, the cores and Drude particles should appear in the data file as standard atoms. The same holds for the springs between them, which are described by standard harmonic bonds. The nature of the atoms (core, Drude particle or non-polarizable) is specified via the "fix drude"_fix_drude.html command. The special list of neighbors is automatically refactored to account for the equivalence of core and Drude particles as regards special 1-2 to 1-4 screening. It may be necessary to use the {extra} keyword of the "special_bonds"_special_bonds.html command. If using "fix shake"_fix_shake.html, make sure no Drude particle is in this fix group. There are two ways to thermostat the Drude particles at a low temperature: use either "fix langevin/drude"_fix_langevin_drude.html for a Langevin thermostat, or "fix drude/transform/*"_fix_drude_transform.html for a Nose-Hoover thermostat. The former requires use of the command "comm_modify vel yes"_comm_modify.html. The latter requires two separate integration fixes like {nvt} or {npt}. The correct temperatures of the reduced degrees of freedom can be calculated using the "compute temp/drude"_compute_temp_drude.html. This requires also to use the command {comm_modify vel yes}. Short-range damping of the induced dipole interactions can be achieved using Thole functions through the the "pair style thole"_pair_thole.html in "pair_style hybrid/overlay"_pair_hybrid.html with a Coulomb pair style. It may be useful to use {coul/long/cs} or similar from the CORESHELL package if the core and Drude particle come too close, which can cause numerical issues. :line :line :link(howto-Berendsen) [(Berendsen)] Berendsen, Grigera, Straatsma, J Phys Chem, 91, 6269-6271 (1987). :link(howto-Cornell) [(Cornell)] Cornell, Cieplak, Bayly, Gould, Merz, Ferguson, Spellmeyer, Fox, Caldwell, Kollman, JACS 117, 5179-5197 (1995). :link(Horn) [(Horn)] Horn, Swope, Pitera, Madura, Dick, Hura, and Head-Gordon, J Chem Phys, 120, 9665 (2004). :link(howto-Ikeshoji) [(Ikeshoji)] Ikeshoji and Hafskjold, Molecular Physics, 81, 251-261 (1994). :link(howto-Wirnsberger) [(Wirnsberger)] Wirnsberger, Frenkel, and Dellago, J Chem Phys, 143, 124104 (2015). :link(howto-MacKerell) [(MacKerell)] MacKerell, Bashford, Bellott, Dunbrack, Evanseck, Field, Fischer, Gao, Guo, Ha, et al, J Phys Chem, 102, 3586 (1998). :link(howto-Mayo) [(Mayo)] Mayo, Olfason, Goddard III, J Phys Chem, 94, 8897-8909 (1990). :link(Jorgensen) [(Jorgensen)] Jorgensen, Chandrasekhar, Madura, Impey, Klein, J Chem Phys, 79, 926 (1983). :link(Price) [(Price)] Price and Brooks, J Chem Phys, 121, 10096 (2004). :link(Shinoda) [(Shinoda)] Shinoda, Shiga, and Mikami, Phys Rev B, 69, 134103 (2004). :link(MitchellFinchham) [(Mitchell and Finchham)] Mitchell, Finchham, J Phys Condensed Matter, 5, 1031-1038 (1993). :link(howto-Lamoureux) [(Lamoureux and Roux)] G. Lamoureux, B. Roux, J. Chem. Phys 119, 3025 (2003) diff --git a/doc/src/Section_python.txt b/doc/src/Section_python.txt index 4bfb1fbdb..64fa11970 100644 --- a/doc/src/Section_python.txt +++ b/doc/src/Section_python.txt @@ -1,819 +1,819 @@ "Previous Section"_Section_modify.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next Section"_Section_errors.html :c :link(lws,http://lammps.sandia.gov) :link(ld,Manual.html) :link(lc,Section_commands.html#comm) :line 11. Python interface to LAMMPS :h3 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. 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. This section describes how to do both. 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 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. See "Section 6.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 6.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. 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. Ctypes is part of standard Python for versions 2.5 and later. You can 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 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 branching 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 :pre 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.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 2.5"_Section_start.html#start_5. A shared library is one 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 make foo mode=shlib :pre where foo is the machine target name, such as linux or g++ or serial. This should create the file liblammps_foo.so in the src directory, as well as a soft link liblammps.so, which is what the Python wrapper will load by default. Note that if you are building multiple machine versions of the shared library, the soft link is always set to the most recently built version. NOTE: If you are building LAMMPS with an MPI or FFT library or other auxiliary libraries (used by various packages), then all of these extra libraries must also be shared libraries. If the LAMMPS shared-library build fails with an error complaining about this, see "Section 2.5"_Section_start.html#start_5 for more details. :line 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: python/lammps.py src/liblammps.so :ul Lammps.py is the Python wrapper on the LAMMPS library interface. Liblammps.so is the shared LAMMPS library that Python loads, as described above. You can insure Python can find these files in one of two ways: set two environment variables run the python/install.py script :ul If you set the paths to these files as environment variables, you only have to do it once. For the csh or tcsh shells, add something like this to your ~/.cshrc file, one line for each of the two files: setenv PYTHONPATH $\{PYTHONPATH\}:/home/sjplimp/lammps/python setenv LD_LIBRARY_PATH $\{LD_LIBRARY_PATH\}:/home/sjplimp/lammps/src :pre If you use the python/install.py script, you need to invoke it every time you rebuild LAMMPS (as a shared library) or make changes to the python/lammps.py file. You can invoke install.py from the python directory as % python install.py \[libdir\] \[pydir\] :pre The optional libdir is where to copy the LAMMPS shared library to; the default is /usr/local/lib. The optional pydir is where to copy the lammps.py file to; the default is the site-packages directory of the version of Python that is running the install script. Note that libdir must be a location that is in your default LD_LIBRARY_PATH, like /usr/local/lib or /usr/lib. And pydir must be a location that Python looks in by default for imported modules, like its site-packages dir. If you want to copy these files to non-standard locations, such as within your own user space, you will need to set your PYTHONPATH and LD_LIBRARY_PATH environment variables accordingly, as above. If the install.py script does not allow you to copy files into system directories, prefix the python command with "sudo". If you do this, make sure that the Python that root runs is the same as the Python you run. E.g. you may need to do something like % sudo /usr/local/bin/python install.py \[libdir\] \[pydir\] :pre You can also invoke install.py from the make command in the src directory as % make install-python :pre In this mode you cannot append optional arguments. Again, you may need to prefix this with "sudo". In this mode you cannot control which Python is invoked by root. Note that if you want Python to be able to load different versions of the LAMMPS shared library (see "this section"_#py_5 below), you will need to manually copy files like liblammps_g++.so into the appropriate system directory. This is not needed if you set the LD_LIBRARY_PATH environment variable as described above. :line 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 make MPI calls directly from Python in your script, if you desire. There are several Python packages available that purport to wrap MPI as a library and allow MPI functions to be called from Python. However, development on most of them seems to be halted except on: "mpi4py"_https://bitbucket.org/mpi4py/mpi4py "PyPar"_https://github.com/daleroberts/pypar :ul Both packages, PyPar and mpi4py have been successfully tested with LAMMPS. PyPar is simpler and easy to set up and use, but supports only a subset of MPI. Mpi4py is more MPI-feature complete, but also a bit more complex to use. As of version 2.0.0, mpi4py is the only python MPI wrapper that allows passing a custom MPI communicator to the LAMMPS constructor, which means one can easily run one or more LAMMPS instances on subsets of the total MPI ranks. :line PyPar requires the ubiquitous "Numpy package"_http://numpy.scipy.org be installed in your Python. After launching Python, type import numpy :pre to see if it is installed. If not, here is how to install it (version 1.3.0b1 as of April 2009). Unpack the numpy tarball and from its top-level directory, type python setup.py build sudo python setup.py install :pre The "sudo" is only needed if required to copy Numpy files into your Python distribution's site-packages directory. To install PyPar (version pypar-2.1.4_94 as of Aug 2012), unpack it and from its "source" directory, type python setup.py build sudo python setup.py install :pre Again, the "sudo" is only needed if required to copy PyPar files into your Python distribution's site-packages directory. If you have successully installed PyPar, you should be able to run Python and type import pypar :pre without error. You should also be able to run python in parallel on a simple test script % mpirun -np 4 python test.py :pre where test.py contains the lines import pypar print "Proc %d out of %d procs" % (pypar.rank(),pypar.size()) :pre and see one line of output for each processor you run on. NOTE: To use PyPar and LAMMPS in parallel from Python, you must insure both are using the same version of MPI. If you only have one MPI installed on your system, this is not an issue, but it can be if you have multiple MPIs. Your LAMMPS build is explicit about which MPI it is using, since you specify the details in your lo-level src/MAKE/Makefile.foo file. PyPar uses the "mpicc" command to find information about the MPI it uses to build against. And it tries to load "libmpi.so" from the LD_LIBRARY_PATH. This may or may not find the MPI library that LAMMPS is using. If you have problems running both PyPar and LAMMPS together, this is an issue you may need to address, e.g. by moving other MPI installations so that PyPar finds the right one. :line To install mpi4py (version mpi4py-2.0.0 as of Oct 2015), unpack it and from its main directory, type python setup.py build sudo python setup.py install :pre Again, the "sudo" is only needed if required to copy mpi4py files into your Python distribution's site-packages directory. To install with user privilege into the user local directory type python setup.py install --user :pre If you have successully installed mpi4py, you should be able to run Python and type from mpi4py import MPI :pre without error. You should also be able to run python in parallel on a simple test script % mpirun -np 4 python test.py :pre where test.py contains the lines from mpi4py import MPI comm = MPI.COMM_WORLD print "Proc %d out of %d procs" % (comm.Get_rank(),comm.Get_size()) :pre and see one line of output for each processor you run on. NOTE: To use mpi4py and LAMMPS in parallel from Python, you must insure both are using the same version of MPI. If you only have one MPI installed on your system, this is not an issue, but it can be if you have multiple MPIs. Your LAMMPS build is explicit about which MPI it is using, since you specify the details in your lo-level src/MAKE/Makefile.foo file. Mpi4py uses the "mpicc" command to find information about the MPI it uses to build against. And it tries to load "libmpi.so" from the LD_LIBRARY_PATH. This may or may not find the MPI library that LAMMPS is using. If you have problems running both mpi4py and LAMMPS together, this is an issue you may need to address, e.g. by moving other MPI installations so that mpi4py finds the right one. :line 11.6 Testing the Python-LAMMPS interface :link(py_6),h4 To test if LAMMPS is callable from Python, launch Python interactively and type: >>> from lammps import lammps >>> lmp = lammps() :pre If you get no errors, you're ready to use LAMMPS from Python. If the 2nd command fails, the most common error to see is OSError: Could not load LAMMPS dynamic library :pre which means Python was unable to load the LAMMPS shared library. This typically occurs if the system can't find the LAMMPS shared library or one of the auxiliary shared libraries it depends on, or if something about the library is incompatible with your Python. The error message should give you an indication of what went wrong. You can also test the load directly in Python as follows, without first importing from the lammps.py file: >>> from ctypes import CDLL >>> CDLL("liblammps.so") :pre If an error occurs, carefully go thru the steps in "Section 2.5"_Section_start.html#start_5 and above about building a shared library and about insuring Python can find the necessary two files it needs. [Test LAMMPS and Python in serial:] :h5 To run a LAMMPS test in serial, type these lines into Python interactively from the bench directory: >>> from lammps import lammps >>> lmp = lammps() >>> lmp.file("in.lj") :pre Or put the same lines in the file test.py and run it as % python test.py :pre Either way, you should see the results of running the in.lj benchmark on a single processor appear on the screen, the same as if you had typed something like: lmp_g++ -in in.lj :pre [Test LAMMPS and Python in parallel:] :h5 To run LAMMPS in parallel, assuming you have installed the "PyPar"_https://github.com/daleroberts/pypar package as discussed above, create a test.py file containing these lines: import pypar from lammps import lammps lmp = lammps() lmp.file("in.lj") print "Proc %d out of %d procs has" % (pypar.rank(),pypar.size()),lmp pypar.finalize() :pre To run LAMMPS in parallel, assuming you have installed the "mpi4py"_https://bitbucket.org/mpi4py/mpi4py package as discussed above, create a test.py file containing these lines: from mpi4py import MPI from lammps import lammps lmp = lammps() lmp.file("in.lj") me = MPI.COMM_WORLD.Get_rank() nprocs = MPI.COMM_WORLD.Get_size() print "Proc %d out of %d procs has" % (me,nprocs),lmp MPI.Finalize() :pre You can either script in parallel as: % mpirun -np 4 python test.py :pre and you should see the same output as if you had typed % mpirun -np 4 lmp_g++ -in in.lj :pre Note that if you leave out the 3 lines from test.py that specify PyPar commands you will instantiate and run LAMMPS independently on each of the P processors specified in the mpirun command. In this case you should get 4 sets of output, each showing that a LAMMPS run was made on a single processor, instead of one set of output showing that LAMMPS ran on 4 processors. If the 1-processor outputs occur, it means that PyPar is not working correctly. Also note that once you import the PyPar module, PyPar initializes MPI for you, and you can use MPI calls directly in your Python script, as described in the PyPar documentation. The last line of your Python script should be pypar.finalize(), to insure MPI is shut down correctly. [Running Python scripts:] :h5 Note that any Python script (not just for LAMMPS) can be invoked in one of several ways: % python foo.script % python -i foo.script % foo.script :pre The last command requires that the first line of the script be something like this: #!/usr/local/bin/python #!/usr/local/bin/python -i :pre where the path points to where you have Python installed, and that you have made the script file executable: % chmod +x foo.script :pre Without the "-i" flag, Python will exit when the script finishes. With the "-i" flag, you will be left in the Python interpreter when the script finishes, so you can type subsequent commands. As mentioned above, you can only run Python interactively when running Python on a single processor, not in parallel. :line :line 11.7 Using LAMMPS from Python :link(py_7),h4 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 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 4 optional args are allowed: name, cmdargs, ptr, comm lmp = lammps(ptr=lmpptr) # use lmpptr as previously created LAMMPS object lmp = lammps(comm=split) # create a LAMMPS object with a custom communicator, requires mpi4py 2.0.0 or later lmp = lammps(name="g++") # create a LAMMPS object using the liblammps_g++.so library lmp = lammps(name="g++",cmdargs=list) # add LAMMPS command-line args, e.g. list = \["-echo","screen"\] :pre lmp.close() # destroy a LAMMPS object :pre version = lmp.version() # return the numerical version id, e.g. LAMMPS 2 Sep 2015 -> 20150902 lmp.file(file) # run an entire input script, file = "in.lj" lmp.command(cmd) # invoke a single LAMMPS command, cmd = "run 100" :pre xlo = lmp.extract_global(name,type) # extract a global quantity # name = "boxxlo", "nlocal", etc - # type = 0 = int - # 1 = double :pre + # type = 0 = int + # 1 = double :pre coords = lmp.extract_atom(name,type) # extract a per-atom quantity # name = "x", "type", etc - # type = 0 = vector of ints - # 1 = array of ints - # 2 = vector of doubles - # 3 = array of doubles :pre + # type = 0 = vector of ints + # 1 = array of ints + # 2 = vector of doubles + # 3 = array of doubles :pre eng = lmp.extract_compute(id,style,type) # extract value(s) from a compute v3 = lmp.extract_fix(id,style,type,i,j) # extract value(s) from a fix # id = ID of compute or fix - # style = 0 = global data - # 1 = per-atom data - # 2 = local data - # type = 0 = scalar - # 1 = vector - # 2 = array - # i,j = indices of value in global vector or array :pre + # style = 0 = global data + # 1 = per-atom data + # 2 = local data + # type = 0 = scalar + # 1 = vector + # 2 = array + # i,j = indices of value in global vector or array :pre var = lmp.extract_variable(name,group,flag) # extract value(s) from a variable - # name = name of variable - # group = group ID (ignored for equal-style variables) - # flag = 0 = equal-style variable - # 1 = atom-style variable :pre + # name = name of variable + # group = group ID (ignored for equal-style variables) + # flag = 0 = equal-style variable + # 1 = atom-style variable :pre flag = lmp.set_variable(name,value) # set existing named string-style variable to value, flag = 0 if successful natoms = lmp.get_natoms() # total # of atoms as int data = lmp.gather_atoms(name,type,count) # return atom attribute of all atoms gathered into data, ordered by atom ID # name = "x", "charge", "type", etc # count = # of per-atom values, 1 or 3, etc lmp.scatter_atoms(name,type,count,data) # scatter atom attribute of all atoms from data, ordered by atom ID # name = "x", "charge", "type", etc # count = # of per-atom values, 1 or 3, etc :pre :line 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. from lammps import lammps lmp1 = lammps() lmp2 = lammps() lmp1.file("in.file1") lmp2.file("in.file2") :pre The file() and command() methods allow an input script or single commands to be invoked. The extract_global(), extract_atom(), extract_compute(), extract_fix(), and extract_variable() methods return values or pointers to data structures internal to LAMMPS. For extract_global() see the src/library.cpp file for the list of valid names. New names could easily be added. A double or integer is returned. You need to specify the appropriate data type via the type argument. For extract_atom(), a pointer to internal LAMMPS atom-based data is returned, which you can use via normal Python subscripting. See the extract() method in the src/atom.cpp file for a list of valid names. Again, new names could easily be added. A pointer to a vector of doubles or integers, or a pointer to an array of doubles (double **) or integers (int **) is returned. You need to specify the appropriate data type via the type argument. For extract_compute() and extract_fix(), the global, per-atom, or local data calulated by the compute or fix can be accessed. What is returned depends on whether the compute or fix calculates a scalar or vector or array. For a scalar, a single double value is returned. If the compute or fix calculates a vector or array, a pointer to the internal LAMMPS data is returned, which you can use via normal Python subscripting. The one exception is that for a fix that calculates a global vector or array, a single double value from the vector or array is returned, indexed by I (vector) or I and J (array). I,J are zero-based indices. The I,J arguments can be left out if not needed. See "Section 6.15"_Section_howto.html#howto_15 of the manual for a discussion of global, per-atom, and local data, and of scalar, vector, and array data types. See the doc pages for individual "computes"_compute.html and "fixes"_fix.html for a description of what they calculate and store. For extract_variable(), an "equal-style or atom-style variable"_variable.html is evaluated and its result returned. For equal-style variables a single double value is returned and the group argument is ignored. For atom-style variables, a vector of doubles is returned, one value per atom, which you can use via normal Python subscripting. The values will be zero for atoms not in the specified group. The get_natoms() method returns the total number of atoms in the simulation, as an int. The gather_atoms() method returns a ctypes vector of ints or doubles as specified by type, of length count*natoms, for the property of all the atoms in the simulation specified by name, ordered by count and then by atom ID. The vector can be used via normal Python subscripting. If atom IDs are not consecutively ordered within LAMMPS, a None is returned as indication of an error. Note that the data structure gather_atoms("x") returns is different from the data structure returned by extract_atom("x") in four ways. (1) Gather_atoms() returns a vector which you index as x\[i\]; extract_atom() returns an array which you index as x\[i\]\[j\]. (2) Gather_atoms() orders the atoms by atom ID while extract_atom() does not. (3) Gathert_atoms() returns a list of all atoms in the simulation; extract_atoms() returns just the atoms local to each processor. (4) Finally, the gather_atoms() data structure is a copy of the atom coords stored internally in LAMMPS, whereas extract_atom() returns an array that effectively points directly to the internal data. This means you can change values inside LAMMPS from Python by assigning a new values to the extract_atom() array. To do this with the gather_atoms() vector, you need to change values in the vector, then invoke the scatter_atoms() method. The scatter_atoms() method takes a vector of ints or doubles as specified by type, of length count*natoms, for the property of all the atoms in the simulation specified by name, ordered by bount and then by atom ID. It uses the vector of data to overwrite the corresponding properties for each atom inside LAMMPS. This requires LAMMPS to have its "map" option enabled; see the "atom_modify"_atom_modify.html command for details. If it is not, or if atom IDs are not consecutively ordered, no coordinates are reset. The array of coordinates passed to scatter_atoms() must be a ctypes vector of ints or doubles, allocated and initialized something like this: from ctypes import * natoms = lmp.get_natoms() n3 = 3*natoms x = (n3*c_double)() x\[0\] = x coord of atom with ID 1 x\[1\] = y coord of atom with ID 1 x\[2\] = z coord of atom with ID 1 x\[3\] = x coord of atom with ID 2 ... x\[n3-1\] = z coord of atom with ID natoms lmp.scatter_coords("x",1,3,x) :pre Alternatively, you can just change values in the vector returned by gather_atoms("x",1,3), since it is a ctypes vector of doubles. :line As noted above, these Python class methods correspond one-to-one with the functions in the LAMMPS library interface in src/library.cpp and library.h. This means you can extend the Python wrapper via the following steps: Add a new interface function to src/library.cpp and src/library.h. :ulb,l Rebuild LAMMPS as a shared library. :l Add a wrapper method to python/lammps.py for this interface function. :l You should now be able to invoke the new interface function from a Python script. Isn't ctypes amazing? :l :ule :line :line 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 things that are possible when Python wraps LAMMPS. If you create your own scripts, send them to us and we can include them in the LAMMPS distribution. trivial.py, read/run a LAMMPS input script thru Python, demo.py, invoke various LAMMPS library interface routines, simple.py, run in parallel, similar to examples/COUPLE/simple/simple.cpp, split.py, same as simple.py but running in parallel on a subset of procs, gui.py, GUI go/stop/temperature-slider to control LAMMPS, plot.py, real-time temeperature plot with GnuPlot via Pizza.py, viz_tool.py, real-time viz via some viz package, vizplotgui_tool.py, combination of viz_tool.py and plot.py and gui.py :tb(c=2) :line For the viz_tool.py and vizplotgui_tool.py commands, replace "tool" with "gl" or "atomeye" or "pymol" or "vmd", depending on what visualization package you have installed. Note that for GL, you need to be able to run the Pizza.py GL tool, which is included in the pizza sub-directory. See the "Pizza.py doc pages"_pizza for more info: :link(pizza,http://www.sandia.gov/~sjplimp/pizza.html) Note that for AtomEye, you need version 3, and there is a line in the scripts that specifies the path and name of the executable. See the AtomEye WWW pages "here"_atomeye or "here"_atomeye3 for more details: http://mt.seas.upenn.edu/Archive/Graphics/A http://mt.seas.upenn.edu/Archive/Graphics/A3/A3.html :pre :link(atomeye,http://mt.seas.upenn.edu/Archive/Graphics/A) :link(atomeye3,http://mt.seas.upenn.edu/Archive/Graphics/A3/A3.html) The latter link is to AtomEye 3 which has the scriping capability needed by these Python scripts. Note that for PyMol, you need to have built and installed the open-source version of PyMol in your Python, so that you can import it from a Python script. See the PyMol WWW pages "here"_pymolhome or "here"_pymolopen for more details: http://www.pymol.org http://sourceforge.net/scm/?type=svn&group_id=4546 :pre :link(pymolhome,http://www.pymol.org) :link(pymolopen,http://sourceforge.net/scm/?type=svn&group_id=4546) The latter link is to the open-source version. Note that for VMD, you need a fairly current version (1.8.7 works for me) and there are some lines in the pizza/vmd.py script for 4 PIZZA variables that have to match the VMD installation on your system. :line See the python/README file for instructions on how to run them and the source code for individual scripts for comments about what they do. Here are screenshots of the vizplotgui_tool.py script in action for different visualization package options. Click to see larger images: :image(JPG/screenshot_gl_small.jpg,JPG/screenshot_gl.jpg) :image(JPG/screenshot_atomeye_small.jpg,JPG/screenshot_atomeye.jpg) :image(JPG/screenshot_pymol_small.jpg,JPG/screenshot_pymol.jpg) :image(JPG/screenshot_vmd_small.jpg,JPG/screenshot_vmd.jpg) diff --git a/doc/src/atom_style.txt b/doc/src/atom_style.txt index 3a8c5d045..e632d0018 100644 --- a/doc/src/atom_style.txt +++ b/doc/src/atom_style.txt @@ -1,301 +1,301 @@ "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 atom_style command :h3 [Syntax:] atom_style style args :pre style = {angle} or {atomic} or {body} or {bond} or {charge} or {dipole} or \ {dpd} or {electron} or {ellipsoid} or {full} or {line} or {meso} or \ - {molecular} or {peri} or {smd} or {sphere} or {tri} or \ + {molecular} or {peri} or {smd} or {sphere} or {tri} or \ {template} or {hybrid} :ulb,l args = none for any style except the following {body} args = bstyle bstyle-args bstyle = style of body particles bstyle-args = additional arguments specific to the bstyle see the "body"_body.html doc page for details {template} args = template-ID template-ID = ID of molecule template specified in a separate "molecule"_molecule.html command {hybrid} args = list of one or more sub-styles, each with their args :pre accelerated styles (with same args) = {angle/kk} or {atomic/kk} or {bond/kk} or {charge/kk} or {full/kk} or {molecular/kk} :l :ule [Examples:] atom_style atomic atom_style bond atom_style full atom_style body nparticle 2 10 atom_style hybrid charge bond atom_style hybrid charge body nparticle 2 5 atom_style template myMols :pre [Description:] Define what style of atoms to use in a simulation. This determines what attributes are associated with the atoms. This command must be used before a simulation is setup via a "read_data"_read_data.html, "read_restart"_read_restart.html, or "create_box"_create_box.html command. NOTE: Many of the atom styles discussed here are only enabled if LAMMPS was built with a specific package, as listed below in the Restrictions section. Once a style is assigned, it cannot be changed, so use a style general enough to encompass all attributes. E.g. with style {bond}, angular terms cannot be used or added later to the model. It is OK to use a style more general than needed, though it may be slightly inefficient. The choice of style affects what quantities are stored by each atom, what quantities are communicated between processors to enable forces to be computed, and what quantities are listed in the data file read by the "read_data"_read_data.html command. These are the additional attributes of each style and the typical kinds of physical systems they are used to model. All styles store coordinates, velocities, atom IDs and types. See the "read_data"_read_data.html, "create_atoms"_create_atoms.html, and "set"_set.html commands for info on how to set these various quantities. {angle} | bonds and angles | bead-spring polymers with stiffness | {atomic} | only the default values | coarse-grain liquids, solids, metals | {body} | mass, inertia moments, quaternion, angular momentum | arbitrary bodies | {bond} | bonds | bead-spring polymers | {charge} | charge | atomic system with charges | {dipole} | charge and dipole moment | system with dipolar particles | {dpd} | internal temperature and internal energies | DPD particles | {electron} | charge and spin and eradius | electronic force field | {ellipsoid} | shape, quaternion, angular momentum | aspherical particles | {full} | molecular + charge | bio-molecules | {line} | end points, angular velocity | rigid bodies | {meso} | rho, e, cv | SPH particles | {molecular} | bonds, angles, dihedrals, impropers | uncharged molecules | {peri} | mass, volume | mesocopic Peridynamic models | {smd} | volume, kernel diameter, contact radius, mass | solid and fluid SPH particles | {sphere} | diameter, mass, angular velocity | granular models | {template} | template index, template atom | small molecules with fixed topology | {tri} | corner points, angular momentum | rigid bodies | {wavepacket} | charge, spin, eradius, etag, cs_re, cs_im | AWPMD :tb(c=3,s=|) NOTE: It is possible to add some attributes, such as a molecule ID, to atom styles that do not have them via the "fix property/atom"_fix_property_atom.html command. This command also allows new custom attributes consisting of extra integer or floating-point values to be added to atoms. See the "fix property/atom"_fix_property_atom.html doc page for examples of cases where this is useful and details on how to initialize, access, and output the custom values. All of the above styles define point particles, except the {sphere}, {ellipsoid}, {electron}, {peri}, {wavepacket}, {line}, {tri}, and {body} styles, which define finite-size particles. See "Section 6.14"_Section_howto.html#howto_14 for an overview of using finite-size particle models with LAMMPS. All of the point-particle styles assign mass to particles on a per-type basis, using the "mass"_mass.html command, The finite-size particle styles assign mass to individual particles on a per-particle basis. For the {sphere} style, the particles are spheres and each stores a per-particle diameter and mass. If the diameter > 0.0, the particle is a finite-size sphere. If the diameter = 0.0, it is a point particle. For the {ellipsoid} style, the particles are ellipsoids and each stores a flag which indicates whether it is a finite-size ellipsoid or a point particle. If it is an ellipsoid, it also stores a shape vector with the 3 diamters of the ellipsoid and a quaternion 4-vector with its orientation. For the {dipole} style, a point dipole is defined for each point particle. Note that if you wish the particles to be finite-size spheres as in a Stockmayer potential for a dipolar fluid, so that the particles can rotate due to dipole-dipole interactions, then you need to use atom_style hybrid sphere dipole, which will assign both a diameter and dipole moment to each particle. For the {electron} style, the particles representing electrons are 3d Gaussians with a specified position and bandwidth or uncertainty in position, which is represented by the eradius = electron size. For the {peri} style, the particles are spherical and each stores a per-particle mass and volume. The {dpd} style is for dissipative particle dynamics (DPD) particles. Note that it is part of the USER-DPD package, and is not for use with the "pair_style dpd or dpd/stat"_pair_dpd.html commands, which can simply use atom_style atomic. Atom_style dpd extends DPD particle properties with internal temperature (dpdTheta), internal conductive energy (uCond), internal mechanical energy (uMech), and internal chemical energy (uChem). The {meso} style is for smoothed particle hydrodynamics (SPH) particles which store a density (rho), energy (e), and heat capacity (cv). The {smd} style is for a general formulation of Smooth Particle Hydrodynamics. Both fluids and solids can be modeled. Particles store the mass and volume of an integration point, a kernel diameter used for calculating the field variables (e.g. stress and deformation) and a contact radius for calculating repulsive forces which prevent individual physical bodies from penetretating each other. The {wavepacket} style is similar to {electron}, but the electrons may consist of several Gaussian wave packets, summed up with coefficients cs= (cs_re,cs_im). Each of the wave packets is treated as a separate particle in LAMMPS, wave packets belonging to the same electron must have identical {etag} values. For the {line} style, the particles are idealized line segments and each stores a per-particle mass and length and orientation (i.e. the end points of the line segment). For the {tri} style, the particles are planar triangles and each stores a per-particle mass and size and orientation (i.e. the corner points of the triangle). The {template} style allows molecular topolgy (bonds,angles,etc) to be defined via a molecule template using the "molecule"_molecule.txt command. The template stores one or more molecules with a single copy of the topology info (bonds,angles,etc) of each. Individual atoms only store a template index and template atom to identify which molecule and which atom-within-the-molecule they represent. Using the {template} style instead of the {bond}, {angle}, {molecular} styles can save memory for systems comprised of a large number of small molecules, all of a single type (or small number of types). See the paper by Grime and Voth, in "(Grime)"_#Grime, for examples of how this can be advantageous for large-scale coarse-grained systems. NOTE: When using the {template} style with a "molecule template"_molecule.html that contains multiple molecules, you should insure the atom types, bond types, angle_types, etc in all the molecules are consistent. E.g. if one molecule represents H2O and another CO2, then you probably do not want each molecule file to define 2 atom types and a single bond type, because they will conflict with each other when a mixture system of H2O and CO2 molecules is defined, e.g. by the "read_data"_read_data.html command. Rather the H2O molecule should define atom types 1 and 2, and bond type 1. And the CO2 molecule should define atom types 3 and 4 (or atom types 3 and 2 if a single oxygen type is desired), and bond type 2. For the {body} style, the particles are arbitrary bodies with internal attributes defined by the "style" of the bodies, which is specified by the {bstyle} argument. Body particles can represent complex entities, such as surface meshes of discrete points, collections of sub-particles, deformable objects, etc. The "body"_body.html doc page descibes the body styles LAMMPS currently supports, and provides more details as to the kind of body particles they represent. For all styles, each body particle stores moments of inertia and a quaternion 4-vector, so that its orientation and position can be time integrated due to forces and torques. Note that there may be additional arguments required along with the {bstyle} specification, in the atom_style body command. These arguments are described in the "body"_body.html doc page. :line Typically, simulations require only a single (non-hybrid) atom style. If some atoms in the simulation do not have all the properties defined by a particular style, use the simplest style that defines all the needed properties by any atom. For example, if some atoms in a simulation are charged, but others are not, use the {charge} style. If some atoms have bonds, but others do not, use the {bond} style. The only scenario where the {hybrid} style is needed is if there is no single style which defines all needed properties of all atoms. For example, as mentioned above, if you want dipolar particles which will rotate due to torque, you need to use "atom_style hybrid sphere dipole". When a hybrid style is used, atoms store and communicate the union of all quantities implied by the individual styles. When using the {hybrid} style, you cannot combine the {template} style with another molecular style that stores bond,angle,etc info on a per-atom basis. LAMMPS can be extended with new atom styles as well as new body styles; see "this section"_Section_modify.html. :line Styles with a {kk} suffix are functionally the same as the corresponding style without the suffix. They have been optimized to run faster, depending on your available hardware, as discussed in "Section 5"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. Note that other acceleration packages in LAMMPS, specifically the GPU, USER-INTEL, USER-OMP, and OPT packages do not use accelerated atom styles. The accelerated styles are part of the KOKKOS package. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. You can specify the accelerated styles explicitly in your input script by including their suffix, or you can use the "-suffix command-line switch"_Section_start.html#start_7 when you invoke LAMMPS, or you can use the "suffix"_suffix.html command in your input script. See "Section 5"_Section_accelerate.html of the manual for more instructions on how to use the accelerated styles effectively. [Restrictions:] This command cannot be used after the simulation box is defined by a "read_data"_read_data.html or "create_box"_create_box.html command. Many of the styles listed above are only enabled if LAMMPS was built with a specific package, as listed below. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. The {angle}, {bond}, {full}, {molecular}, and {template} styles are part of the MOLECULE package. The {line} and {tri} styles are part of the ASPHERE package. The {body} style is part of the BODY package. The {dipole} style is part of the DIPOLE package. The {peri} style is part of the PERI package for Peridynamics. The {electron} style is part of the USER-EFF package for "electronic force fields"_pair_eff.html. The {dpd} style is part of the USER-DPD package for dissipative particle dynamics (DPD). The {meso} style is part of the USER-SPH package for smoothed particle hydrodyanmics (SPH). See "this PDF guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in LAMMPS. The {wavepacket} style is part of the USER-AWPMD package for the "antisymmetrized wave packet MD method"_pair_awpmd.html. [Related commands:] "read_data"_read_data.html, "pair_style"_pair_style.html [Default:] atom_style atomic :line :link(Grime) [(Grime)] Grime and Voth, to appear in J Chem Theory & Computation (2014). diff --git a/doc/src/comm_modify.txt b/doc/src/comm_modify.txt index 6fefc5aeb..3e8d0eca4 100644 --- a/doc/src/comm_modify.txt +++ b/doc/src/comm_modify.txt @@ -1,159 +1,159 @@ "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 comm_modify command :h3 [Syntax:] comm_modify keyword value ... :pre zero or more keyword/value pairs may be appended :ulb,l keyword = {mode} or {cutoff} or {cutoff/multi} or {group} or {vel} :l {mode} value = {single} or {multi} = communicate atoms within a single or multiple distances {cutoff} value = Rcut (distance units) = communicate atoms from this far away {cutoff/multi} type value type = atom type or type range (supports asterisk notation) value = Rcut (distance units) = communicate atoms for selected types from this far away {group} value = group-ID = only communicate atoms in the group {vel} value = {yes} or {no} = do or do not communicate velocity info with ghost atoms :pre :ule [Examples:] comm_modify mode multi comm_modify mode multi group solvent comm_modift mode multi cutoff/multi 1 10.0 cutoff/multi 2*4 15.0 comm_modify vel yes comm_modify mode single cutoff 5.0 vel yes comm_modify cutoff/multi * 0.0 :pre [Description:] This command sets parameters that affect the inter-processor communication of atom information that occurs each timestep as coordinates and other properties are exchanged between neighboring processors and stored as properties of ghost atoms. NOTE: These options apply to the currently defined comm style. When you specify a "comm_style"_comm_style.html command, all communication settings are restored to their default values, including those previously reset by a comm_modify command. Thus if your input script specifies a comm_style command, you should use the comm_modify command after it. The {mode} keyword determines whether a single or multiple cutoff distances are used to determine which atoms to communicate. The default mode is {single} which means each processor acquires information for ghost atoms that are within a single distance from its sub-domain. The distance is by default the maximum of the neighbor cutoff across all atom type pairs. For many systems this is an efficient algorithm, but for systems with widely varying cutoffs for different type pairs, the {multi} mode can be faster. In this case, each atom type is assigned its own distance cutoff for communication purposes, and fewer atoms will be communicated. See the "neighbor multi"_neighbor.html command for a neighbor list construction option that may also be beneficial for simulations of this kind. The {cutoff} keyword allows you to extend the ghost cutoff distance for communication mode {single}, which is the distance from the borders of a processor's sub-domain at which ghost atoms are acquired from other processors. By default the ghost cutoff = neighbor cutoff = pairwise force cutoff + neighbor skin. See the "neighbor"_neighbor.html command for more information about the skin distance. If the specified Rcut is greater than the neighbor cutoff, then extra ghost atoms will be acquired. If the provided cutoff is smaller, the provided value will be ignored and the ghost cutoff is set to the neighbor cutoff. Specifying a cutoff value of 0.0 will reset any previous value to the default. The {cutoff/multi} option is equivalent to {cutoff}, but applies to communication mode {multi} instead. Since in this case the communication cutoffs are determined per atom type, a type specifier is needed and cutoff for one or multiple types can be extended. Also ranges of types using the usual asterisk notation can be given. These are simulation scenarios in which it may be useful or even necessary to set a ghost cutoff > neighbor cutoff: a single polymer chain with bond interactions, but no pairwise interactions bonded interactions (e.g. dihedrals) extend further than the pairwise cutoff ghost atoms beyond the pairwise cutoff are needed for some computation :ul In the first scenario, a pairwise potential is not defined. Thus the pairwise neighbor cutoff will be 0.0. But ghost atoms are still needed for computing bond, angle, etc interactions between atoms on different processors, or when the interaction straddles a periodic boundary. The appropriate ghost cutoff depends on the "newton bond"_newton.html setting. For newton bond {off}, the distance needs to be the furthest distance between any two atoms in the bond, angle, etc. E.g. the distance between 1-4 atoms in a dihedral. For newton bond {on}, the distance between the central atom in the bond, angle, etc and any other atom is sufficient. E.g. the distance between 2-4 atoms in a dihedral. In the second scenario, a pairwise potential is defined, but its neighbor cutoff is not sufficiently long enough to enable bond, angle, etc terms to be computed. As in the previous scenario, an appropriate ghost cutoff should be set. In the last scenario, a "fix"_fix.html or "compute"_compute.html or "pairwise potential"_pair_style.html needs to calculate with ghost atoms beyond the normal pairwise cutoff for some computation it performs (e.g. locate neighbors of ghost atoms in a multibody pair potential). Setting the ghost cutoff appropriately can insure it will find the needed atoms. NOTE: In these scenarios, if you do not set the ghost cutoff long enough, and if there is only one processor in a periodic dimension (e.g. you are running in serial), then LAMMPS may "find" the atom it is looking for (e.g. the partner atom in a bond), that is on the far side of the simulation box, across a periodic boundary. This will typically lead to bad dynamics (i.e. the bond length is now the simulation box length). To detect if this is happening, see the "neigh_modify cluster"_neigh_modify.html command. The {group} keyword will limit communication to atoms in the specified group. This can be useful for models where no ghost atoms are needed for some kinds of particles. All atoms (not just those in the specified group) will still migrate to new processors as they move. The group specified with this option must also be specified via the "atom_modify first"_atom_modify.html command. The {vel} keyword enables velocity information to be communicated with ghost particles. Depending on the "atom_style"_atom_style.html, velocity info includes the translational velocity, angular velocity, and angular momentum of a particle. If the {vel} option is set to {yes}, then ghost atoms store these quantities; if {no} then they do not. The {yes} setting is needed by some pair styles which require the velocity state of both the I and J particles to compute a pairwise -I,J interaction. +I,J interaction, as well as by some compute and fix commands. Note that if the "fix deform"_fix_deform.html command is being used with its "remap v" option enabled, then the velocities for ghost atoms (in the fix deform group) mirrored across a periodic boundary will also include components due to any velocity shift that occurs across that boundary (e.g. due to dilation or shear). [Restrictions:] Communication mode {multi} is currently only available for "comm_style"_comm_style.html {brick}. [Related commands:] "comm_style"_comm_style.html, "neighbor"_neighbor.html [Default:] The option defauls are mode = single, group = all, cutoff = 0.0, vel = no. The cutoff default of 0.0 means that ghost cutoff = neighbor cutoff = pairwise force cutoff + neighbor skin. diff --git a/doc/src/compute_heat_flux.txt b/doc/src/compute_heat_flux.txt index 05eaff57f..720d26ce7 100644 --- a/doc/src/compute_heat_flux.txt +++ b/doc/src/compute_heat_flux.txt @@ -1,190 +1,190 @@ "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 compute heat/flux command :h3 [Syntax:] compute ID group-ID heat/flux ke-ID pe-ID stress-ID :pre ID, group-ID are documented in "compute"_compute.html command heat/flux = style name of this compute command ke-ID = ID of a compute that calculates per-atom kinetic energy pe-ID = ID of a compute that calculates per-atom potential energy stress-ID = ID of a compute that calculates per-atom stress :ul [Examples:] compute myFlux all heat/flux myKE myPE myStress :pre [Description:] Define a computation that calculates the heat flux vector based on contributions from atoms in the specified group. This can be used by itself to measure the heat flux into or out of a reservoir of atoms, or to calculate a thermal conductivity using the Green-Kubo formalism. See the "fix thermal/conductivity"_fix_thermal_conductivity.html command for details on how to compute thermal conductivity in an alternate way, via the Muller-Plathe method. See the "fix heat"_fix_heat.html command for a way to control the heat added or subtracted to a group of atoms. The compute takes three arguments which are IDs of other "computes"_compute.html. One calculates per-atom kinetic energy ({ke-ID}), one calculates per-atom potential energy ({pe-ID)}, and the third calcualtes per-atom stress ({stress-ID}). NOTE: These other computes should provide values for all the atoms in the group this compute specifies. That means the other computes could use the same group as this compute, or they can just use group "all" (or any group whose atoms are superset of the atoms in this compute's group). LAMMPS does not check for this. The Green-Kubo formulas relate the ensemble average of the auto-correlation of the heat flux J to the thermal conductivity kappa: :c,image(Eqs/heat_flux_J.jpg) :c,image(Eqs/heat_flux_k.jpg) Ei in the first term of the equation for J is the per-atom energy (potential and kinetic). This is calculated by the computes {ke-ID} and {pe-ID}. Si in the second term of the equation for J is the per-atom stress tensor calculated by the compute {stress-ID}. The tensor multiplies Vi as a 3x3 matrix-vector multiply to yield a vector. Note that as discussed below, the 1/V scaling factor in the equation for J is NOT included in the calculation performed by this compute; you need to add it for a volume appropriate to the atoms included in the calculation. NOTE: The "compute pe/atom"_compute_pe_atom.html and "compute stress/atom"_compute_stress_atom.html commands have options for which terms to include in their calculation (pair, bond, etc). The heat flux calculation will thus include exactly the same terms. Normally you should use "compute stress/atom virial"_compute_stress_atom.html so as not to include a kinetic energy term in the heat flux. This compute calculates 6 quantities and stores them in a 6-component vector. The first 3 components are the x, y, z components of the full heat flux vector, i.e. (Jx, Jy, Jz). The next 3 components are the x, y, z components of just the convective portion of the flux, i.e. the first term in the equation for J above. :line The heat flux can be output every so many timesteps (e.g. via the "thermo_style custom"_thermo_style.html command). Then as a post-processing operation, an autocorrelation can be performed, its integral estimated, and the Green-Kubo formula above evaluated. The "fix ave/correlate"_fix_ave_correlate.html command can calclate the autocorrelation. The trap() function in the "variable"_variable.html command can calculate the integral. An example LAMMPS input script for solid Ar is appended below. The result should be: average conductivity ~0.29 in W/mK. :line [Output info:] This compute calculates a global vector of length 6 (total heat flux vector, followed by convective heat flux vector), which can be accessed by indices 1-6. These values can be used by any command that uses global vector values from a compute as input. See "this section"_Section_howto.html#howto_15 for an overview of LAMMPS output options. The vector values calculated by this compute are "extensive", meaning they scale with the number of atoms in the simulation. They can be divided by the appropriate volume to get a flux, which would then be an "intensive" value, meaning independent of the number of atoms in the simulation. Note that if the compute is "all", then the appropriate volume to divide by is the simulation box volume. However, if a sub-group is used, it should be the volume containing those atoms. The vector values will be in energy*velocity "units"_units.html. Once divided by a volume the units will be that of flux, namely energy/area/time "units"_units.html [Restrictions:] none [Related commands:] "fix thermal/conductivity"_fix_thermal_conductivity.html, "fix ave/correlate"_fix_ave_correlate.html, "variable"_variable.html [Default:] none :line # Sample LAMMPS input script for thermal conductivity of solid Ar :pre units real variable T equal 70 variable V equal vol variable dt equal 4.0 variable p equal 200 # correlation length variable s equal 10 # sample interval variable d equal $p*$s # dump interval :pre # convert from LAMMPS real units to SI :pre variable kB equal 1.3806504e-23 # \[J/K\] Boltzmann variable kCal2J equal 4186.0/6.02214e23 variable A2m equal 1.0e-10 variable fs2s equal 1.0e-15 variable convert equal $\{kCal2J\}*$\{kCal2J\}/$\{fs2s\}/$\{A2m\} :pre # setup problem :pre dimension 3 boundary p p p lattice fcc 5.376 orient x 1 0 0 orient y 0 1 0 orient z 0 0 1 region box block 0 4 0 4 0 4 create_box 1 box create_atoms 1 box -mass 1 39.948 +mass 1 39.948 pair_style lj/cut 13.0 pair_coeff * * 0.2381 3.405 timestep $\{dt\} -thermo $d :pre +thermo $d :pre # equilibration and thermalization :pre velocity all create $T 102486 mom yes rot yes dist gaussian fix NVT all nvt temp $T $T 10 drag 0.2 run 8000 :pre # thermal conductivity calculation, switch to NVE if desired :pre #unfix NVT #fix NVE all nve :pre reset_timestep 0 compute myKE all ke/atom compute myPE all pe/atom compute myStress all stress/atom NULL virial compute flux all heat/flux myKE myPE myStress variable Jx equal c_flux\[1\]/vol variable Jy equal c_flux\[2\]/vol variable Jz equal c_flux\[3\]/vol fix JJ all ave/correlate $s $p $d & c_flux\[1\] c_flux\[2\] c_flux\[3\] type auto file J0Jt.dat ave running variable scale equal $\{convert\}/$\{kB\}/$T/$T/$V*$s*$\{dt\} variable k11 equal trap(f_JJ\[3\])*$\{scale\} variable k22 equal trap(f_JJ\[4\])*$\{scale\} variable k33 equal trap(f_JJ\[5\])*$\{scale\} thermo_style custom step temp v_Jx v_Jy v_Jz v_k11 v_k22 v_k33 run 100000 variable k equal (v_k11+v_k22+v_k33)/3.0 variable ndens equal count(all)/vol print "average conductivity: $k\[W/mK\] @ $T K, $\{ndens\} /A^3" :pre diff --git a/doc/src/compute_pe_atom.txt b/doc/src/compute_pe_atom.txt index 78c0b8e1e..319983a75 100644 --- a/doc/src/compute_pe_atom.txt +++ b/doc/src/compute_pe_atom.txt @@ -1,100 +1,100 @@ "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 compute pe/atom command :h3 [Syntax:] compute ID group-ID pe/atom keyword ... :pre ID, group-ID are documented in "compute"_compute.html command pe/atom = style name of this compute command zero or more keywords may be appended keyword = {pair} or {bond} or {angle} or {dihedral} or {improper} or {kspace} or {fix} :ul [Examples:] compute 1 all pe/atom compute 1 all pe/atom pair compute 1 all pe/atom pair bond :pre [Description:] Define a computation that computes the per-atom potential energy for each atom in a group. See the "compute pe"_compute_pe.html command if you want the potential energy of the entire system. The per-atom energy is calculated by the various pair, bond, etc potentials defined for the simulation. If no extra keywords are listed, then the potential energy is the sum of pair, bond, angle, dihedral,improper, kspace (long-range), and fix energy. I.e. it is as if all the keywords were listed. If any extra keywords are listed, then only those components are summed to compute the potential energy. Note that the energy of each atom is due to its interaction with all other atoms in the simulation, not just with other atoms in the group. For an energy contribution produced by a small set of atoms (e.g. 4 atoms in a dihedral or 3 atoms in a Tersoff 3-body interaction), that energy is assigned in equal portions to each atom in the set. E.g. 1/4 of the dihedral energy to each of the 4 atoms. The "dihedral_style charmm"_dihedral_charmm.html style calculates pairwise interactions between 1-4 atoms. The energy contribution of these terms is included in the pair energy, not the dihedral energy. The KSpace contribution is calculated using the method in "(Heyes)"_#Heyes for the Ewald method and a related method for PPPM, as specified by the "kspace_style pppm"_kspace_style.html command. For PPPM, the calcluation requires 1 extra FFT each timestep that -per-atom energy is calculated. Thie "document"_PDF/kspace.pdf +per-atom energy is calculated. This "document"_PDF/kspace.pdf describes how the long-range per-atom energy calculation is performed. Various fixes can contribute to the per-atom potential energy of the system if the {fix} contribution is included. See the doc pages for "individual fixes"_fix.html for details of which ones compute a per-atom potential energy. NOTE: The "fix_modify energy yes"_fix_modify.html command must also be specified if a fix is to contribute per-atom potential energy to this command. As an example of per-atom potential energy compared to total potential energy, these lines in an input script should yield the same result in the last 2 columns of thermo output: -compute peratom all pe/atom -compute pe all reduce sum c_peratom -thermo_style custom step temp etotal press pe c_pe :pre +compute peratom all pe/atom +compute pe all reduce sum c_peratom +thermo_style custom step temp etotal press pe c_pe :pre NOTE: The per-atom energy does not any Lennard-Jones tail corrections invoked by the "pair_modify tail yes"_pair_modify.html command, since those are global contributions to the system energy. [Output info:] This compute calculates a per-atom vector, which can be accessed by any command that uses per-atom values from a compute as input. See "Section 6.15"_Section_howto.html#howto_15 for an overview of LAMMPS output options. The per-atom vector values will be in energy "units"_units.html. [Restrictions:] [Related commands:] "compute pe"_compute_pe.html, "compute stress/atom"_compute_stress_atom.html [Default:] none :line :link(Heyes) [(Heyes)] Heyes, Phys Rev B 49, 755 (1994), diff --git a/doc/src/compute_property_atom.txt b/doc/src/compute_property_atom.txt index dd65729c6..bac19918b 100644 --- a/doc/src/compute_property_atom.txt +++ b/doc/src/compute_property_atom.txt @@ -1,163 +1,163 @@ "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 compute property/atom command :h3 [Syntax:] compute ID group-ID property/atom input1 input2 ... :pre ID, group-ID are documented in "compute"_compute.html command :ulb,l property/atom = style name of this compute command :l input = one or more atom attributes :l possible attributes = id, mol, proc, type, mass, - x, y, z, xs, ys, zs, xu, yu, zu, ix, iy, iz, - vx, vy, vz, fx, fy, fz, + x, y, z, xs, ys, zs, xu, yu, zu, ix, iy, iz, + vx, vy, vz, fx, fy, fz, q, mux, muy, muz, mu, radius, diameter, omegax, omegay, omegaz, - angmomx, angmomy, angmomz, - shapex,shapey, shapez, - quatw, quati, quatj, quatk, tqx, tqy, tqz, - end1x, end1y, end1z, end2x, end2y, end2z, - corner1x, corner1y, corner1z, - corner2x, corner2y, corner2z, - corner3x, corner3y, corner3z, - nbonds, + angmomx, angmomy, angmomz, + shapex,shapey, shapez, + quatw, quati, quatj, quatk, tqx, tqy, tqz, + end1x, end1y, end1z, end2x, end2y, end2z, + corner1x, corner1y, corner1z, + corner2x, corner2y, corner2z, + corner3x, corner3y, corner3z, + nbonds, vfrac, s0, - spin, eradius, ervel, erforce, + spin, eradius, ervel, erforce, rho, drho, e, de, cv, i_name, d_name :pre id = atom ID mol = molecule ID proc = ID of processor that owns atom type = atom type mass = atom mass x,y,z = unscaled atom coordinates xs,ys,zs = scaled atom coordinates xu,yu,zu = unwrapped atom coordinates ix,iy,iz = box image that the atom is in vx,vy,vz = atom velocities fx,fy,fz = forces on atoms q = atom charge mux,muy,muz = orientation of dipole moment of atom mu = magnitude of dipole moment of atom radius,diameter = radius,diameter of spherical particle omegax,omegay,omegaz = angular velocity of spherical particle angmomx,angmomy,angmomz = angular momentum of aspherical particle shapex,shapey,shapez = 3 diameters of aspherical particle quatw,quati,quatj,quatk = quaternion components for aspherical or body particles tqx,tqy,tqz = torque on finite-size particles end12x, end12y, end12z = end points of line segment corner123x, corner123y, corner123z = corner points of triangle nbonds = number of bonds assigned to an atom :pre PERI package per-atom properties: vfrac = ??? s0 = ??? :pre USER-EFF and USER-AWPMD package per-atom properties: spin = electron spin eradius = electron radius ervel = electron radial velocity erforce = electron radial force :pre USER-SPH package per-atom properties: rho = ??? drho = ??? e = ??? de = ??? cv = ??? :pre "fix property/atom"_fix_property_atom.html per-atom properties: i_name = custom integer vector with name d_name = custom integer vector with name :pre :ule [Examples:] compute 1 all property/atom xs vx fx mux compute 2 all property/atom type compute 1 all property/atom ix iy iz :pre [Description:] Define a computation that simply stores atom attributes for each atom in the group. This is useful so that the values can be used by other "output commands"_Section_howto.html#howto_15 that take computes as inputs. See for example, the "compute reduce"_compute_reduce.html, "fix ave/atom"_fix_ave_atom.html, "fix ave/histo"_fix_ave_histo.html, "fix ave/chunk"_fix_ave_chunk.html, and "atom-style variable"_variable.html commands. The list of possible attributes is the same as that used by the "dump custom"_dump.html command, which describes their meaning, with some additional quantities that are only defined for certain "atom styles"_atom_style.html. Basically, this augmented list gives an input script access to any per-atom quantity stored by LAMMPS. The values are stored in a per-atom vector or array as discussed below. Zeroes are stored for atoms not in the specified group or for quantities that are not defined for a particular particle in the group (e.g. {shapex} if the particle is not an ellipsoid). The additional quantities only accessible via this command, and not directly via the "dump custom"_dump.html command, are as follows. {Shapex}, {shapey}, and {shapez} are defined for ellipsoidal particles and define the 3d shape of each particle. {Quatw}, {quati}, {quatj}, and {quatk} are defined for ellipsoidal particles and body particles and store the 4-vector quaternion representing the orientation of each particle. See the "set"_set.html command for an explanation of the quaternion vector. {End1x}, {end1y}, {end1z}, {end2x}, {end2y}, {end2z}, are defined for line segment particles and define the end points of each line segment. {Corner1x}, {corner1y}, {corner1z}, {corner2x}, {corner2y}, {corner2z}, {corner3x}, {corner3y}, {corner3z}, are defined for triangular particles and define the corner points of each triangle. {Nbonds} is available for all molecular atom styles and refers to the number of explicit bonds assigned to an atom. Note that if the "newton bond"_newton.html command is set to {on}, which is the default, then every bond in the system is assigned to only one of the two atoms in the bond. Thus a bond between atoms I,J may be tallied for either atom I or atom J. If "newton bond off"_newton.html is set, it will be tallied with both atom I and atom J. The {i_name} and {d_name} attributes refer to custom integer and floating-point properties that have been added to each atom via the "fix property/atom"_fix_property_atom.html command. When that command is used specific names are given to each attribute which are what is specified as the "name" portion of {i_name} or {d_name}. [Output info:] This compute calculates a per-atom vector or per-atom array depending on the number of input values. If a single input is specified, a per-atom vector is produced. If two or more inputs are specified, a per-atom array is produced where the number of columns = the number of inputs. The vector or array can be accessed by any command that uses per-atom values from a compute as input. See "this section"_Section_howto.html#howto_15 for an overview of LAMMPS output options. The vector or array values will be in whatever "units"_units.html the corresponding attribute is in, e.g. velocity units for vx, charge units for q, etc. [Restrictions:] none [Related commands:] "dump custom"_dump.html, "compute reduce"_compute_reduce.html, "fix ave/atom"_fix_ave_atom.html, "fix ave/chunk"_fix_ave_chunk.html, "fix property/atom"_fix_property_atom.html [Default:] none diff --git a/doc/src/compute_property_local.txt b/doc/src/compute_property_local.txt index 98428c19a..bc2ecca46 100644 --- a/doc/src/compute_property_local.txt +++ b/doc/src/compute_property_local.txt @@ -1,157 +1,155 @@ "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 compute property/local command :h3 [Syntax:] compute ID group-ID property/local attribute1 attribute2 ... keyword args ... :pre ID, group-ID are documented in "compute"_compute.html command :ulb,l property/local = style name of this compute command :l one or more attributes may be appended :l - possible attributes = natom1 natom2 ntype1 ntype2 - patom1 patom2 ptype1 ptype2 - batom1 batom2 btype - aatom1 aatom2 aatom3 atype - datom1 datom2 datom3 dtype - iatom1 iatom2 iatom3 itype :pre + possible attributes = natom1 natom2 ntype1 ntype2 + patom1 patom2 ptype1 ptype2 + batom1 batom2 btype + aatom1 aatom2 aatom3 atype + datom1 datom2 datom3 dtype + iatom1 iatom2 iatom3 itype :pre natom1, natom2 = IDs of 2 atoms in each pair (within neighbor cutoff) ntype1, ntype2 = type of 2 atoms in each pair (within neighbor cutoff) patom1, patom2 = IDs of 2 atoms in each pair (within force cutoff) ptype1, ptype2 = type of 2 atoms in each pair (within force cutoff) batom1, batom2 = IDs of 2 atoms in each bond btype = bond type of each bond aatom1, aatom2, aatom3 = IDs of 3 atoms in each angle atype = angle type of each angle datom1, datom2, datom3, datom4 = IDs of 4 atoms in each dihedral dtype = dihedral type of each dihedral iatom1, iatom2, iatom3, iatom4 = IDs of 4 atoms in each improper itype = improper type of each improper :pre zero or more keyword/arg pairs may be appended :l keyword = {cutoff} :l {cutoff} arg = {type} or {radius} :pre :ule [Examples:] compute 1 all property/local btype batom1 batom2 compute 1 all property/local atype aatom2 :pre [Description:] Define a computation that stores the specified attributes as local data so it can be accessed by other "output commands"_Section_howto.html#howto_15. If the input attributes refer to bond information, then the number of datums generated, aggregated across all processors, equals the number of bonds in the system. Ditto for pairs, angles, etc. If multiple attributes are specified then they must all generate the same amount of information, so that the resulting local array has the same number of rows for each column. This means that only bond attributes can be specified together, or angle attributes, etc. Bond and angle attributes can not be mixed in the same compute property/local command. If the inputs are pair attributes, the local data is generated by looping over the pairwise neighbor list. Info about an individual pairwise interaction will only be included if both atoms in the pair are in the specified compute group. For {natom1} and {natom2}, all atom pairs in the neighbor list are considered (out to the neighbor cutoff = force cutoff + "neighbor skin"_neighbor.html). For {patom1} and {patom2}, the distance between the atoms must be less than the force cutoff distance for that pair to be included, as defined by the "pair_style"_pair_style.html and "pair_coeff"_pair_coeff.html commands. The optional {cutoff} keyword determines how the force cutoff distance for an interaction is determined for the {patom1} and {patom2} attributes. For the default setting of {type}, the pairwise cutoff defined by the "pair_style"_pair_style.html command for the types of the two atoms is used. For the {radius} setting, the sum of the radii of the two particles is used as a cutoff. For example, this is appropriate for granular particles which only interact when they are overlapping, as computed by "granular pair styles"_pair_gran.txt. If the inputs are bond, angle, etc attributes, the local data is generated by looping over all the atoms owned on a processor and extracting bond, angle, etc info. For bonds, info about an individual bond will only be included if both atoms in the bond are in the specified compute group. Likewise for angles, dihedrals, etc. For bonds and angles, a bonds/angles that have been broken by setting their bond/angle type to 0 will not be included. Bonds/angles that have been turned off (see the "fix shake"_fix_shake.html or "delete_bonds"_delete_bonds.html commands) by setting their bond/angle type negative are written into the file. This is consistent with the "compute bond/local"_compute_bond_local.html and "compute angle/local"_compute_angle_local.html commands Note that as atoms migrate from processor to processor, there will be no consistent ordering of the entries within the local vector or array from one timestep to the next. The only consistency that is guaranteed is that the ordering on a particular timestep will be the same for local vectors or arrays generated by other compute commands. For example, output from the "compute bond/local"_compute_bond_local.html command can be combined with bond atom indices from this command and output by the "dump local"_dump.html command in a consistent way. The {natom1} and {natom2}, or {patom1} and {patom2} attributes refer to the atom IDs of the 2 atoms in each pairwise interaction computed by the "pair_style"_pair_style.html command. The {ntype1} and {ntype2}, or {ptype1} and {ptype2} attributes refer to the atom types of the 2 atoms in each pairwise interaction. NOTE: For pairs, if two atoms I,J are involved in 1-2, 1-3, 1-4 interactions within the molecular topology, their pairwise interaction may be turned off, and thus they may not appear in the neighbor list, and will not be part of the local data created by this command. More specifically, this may be true of I,J pairs with a weighting factor of 0.0; pairs with a non-zero weighting factor are included. The weighting factors for 1-2, 1-3, and 1-4 pairwise interactions are set by the "special_bonds"_special_bonds.html command. The {batom1} and {batom2} attributes refer to the atom IDs of the 2 atoms in each "bond"_bond_style.html. The {btype} attribute refers to the type of the bond, from 1 to Nbtypes = # of bond types. The number of bond types is defined in the data file read by the "read_data"_read_data.html command. The attributes that start with "a", "d", "i", refer to similar values for "angles"_angle_style.html, "dihedrals"_dihedral_style.html, and "impropers"_improper_style.html. -The optional {cutoff} keyword - [Output info:] This compute calculates a local vector or local array depending on the number of input values. The length of the vector or number of rows in the array is the number of bonds, angles, etc. If a single input is specified, a local vector is produced. If two or more inputs are specified, a local array is produced where the number of columns = the number of inputs. The vector or array can be accessed by any command that uses local values from a compute as input. See "this section"_Section_howto.html#howto_15 for an overview of LAMMPS output options. The vector or array values will be integers that correspond to the specified attribute. [Restrictions:] none [Related commands:] "dump local"_dump.html, "compute reduce"_compute_reduce.html [Default:] The keyword default is cutoff = type. diff --git a/doc/src/compute_reduce.txt b/doc/src/compute_reduce.txt index a0afc8d2c..07d3c3bda 100644 --- a/doc/src/compute_reduce.txt +++ b/doc/src/compute_reduce.txt @@ -1,212 +1,212 @@ "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 compute reduce command :h3 compute reduce/region command :h3 [Syntax:] compute ID group-ID style arg mode input1 input2 ... keyword args ... :pre ID, group-ID are documented in "compute"_compute.html command :ulb,l style = {reduce} or {reduce/region} :l {reduce} arg = none {reduce/region} arg = region-ID region-ID = ID of region to use for choosing atoms :pre mode = {sum} or {min} or {max} or {ave} or {sumsq} or {avesq} :l one or more inputs can be listed :l input = x, y, z, vx, vy, vz, fx, fy, fz, c_ID, c_ID\[N\], f_ID, f_ID\[N\], v_name :l x,y,z,vx,vy,vz,fx,fy,fz = atom attribute (position, velocity, force component) c_ID = per-atom or local vector calculated by a compute with ID c_ID\[I\] = Ith column of per-atom or local array calculated by a compute with ID, I can include wildcard (see below) f_ID = per-atom or local vector calculated by a fix with ID f_ID\[I\] = Ith column of per-atom or local array calculated by a fix with ID, I can include wildcard (see below) v_name = per-atom vector calculated by an atom-style variable with name :pre zero or more keyword/args pairs may be appended :l keyword = {replace} :l {replace} args = vec1 vec2 vec1 = reduced value from this input vector will be replaced vec2 = replace it with vec1\[N\] where N is index of max/min value from vec2 :pre :ule [Examples:] compute 1 all reduce sum c_force compute 1 all reduce/region subbox sum c_force compute 2 all reduce min c_press\[2\] f_ave v_myKE compute 2 all reduce min c_press\[*\] f_ave v_myKE compute 3 fluid reduce max c_index\[1\] c_index\[2\] c_dist replace 1 3 replace 2 3 :pre [Description:] Define a calculation that "reduces" one or more vector inputs into scalar values, one per listed input. The inputs can be per-atom or local quantities; they cannot be global quantities. Atom attributes are per-atom quantities, "computes"_compute.html and "fixes"_fix.html may generate any of the three kinds of quantities, and "atom-style variables"_variable.html generate per-atom quantities. See the "variable"_variable.html command and its special functions which can perform the same operations as the compute reduce command on global vectors. The reduction operation is specified by the {mode} setting. The {sum} option adds the values in the vector into a global total. The {min} or {max} options find the minimum or maximum value across all vector values. The {ave} setting adds the vector values into a global total, then divides by the number of values in the vector. The {sumsq} option sums the square of the values in the vector into a global total. The {avesq} setting does the same as {sumsq}, then divdes the sum of squares by the number of values. The last two options can be useful for calculating the variance of some quantity, e.g. variance = sumsq - ave^2. Each listed input is operated on independently. For per-atom inputs, the group specified with this command means only atoms within the group contribute to the result. For per-atom inputs, if the compute reduce/region command is used, the atoms must also currently be within the region. Note that an input that produces per-atom quantities may define its own group which affects the quantities it returns. For example, if a compute is used as an input which generates a per-atom vector, it will generate values of 0.0 for atoms that are not in the group specified for that compute. Each listed input can be an atom attribute (position, velocity, force component) or can be the result of a "compute"_compute.html or "fix"_fix.html or the evaluation of an atom-style "variable"_variable.html. Note that for values from a compute or fix, the bracketed index I can be specified using a wildcard asterisk with the index to effectively specify multiple values. This takes the form "*" or "*n" or "n*" or "m*n". If N = the size of the vector (for {mode} = scalar) or the number of columns in the array (for {mode} = vector), then an asterisk with no numeric values means all indices from 1 to N. A leading asterisk means all indices from 1 to n (inclusive). A trailing asterisk means all indices from n to N (inclusive). A middle asterisk means all indices from m to n (inclusive). Using a wildcard is the same as if the individual columns of the array had been listed one by one. E.g. these 2 compute reduce commands are equivalent, since the "compute stress/atom"_compute_stress_atom.html command creates a per-atom array with 6 columns: compute myPress all stress/atom NULL compute 2 all reduce min myPress\[*\] compute 2 all reduce min myPress\[1\] myPress\[2\] myPress\[3\] & myPress\[4\] myPress\[5\] myPress\[6\] :pre :line The atom attribute values (x,y,z,vx,vy,vz,fx,fy,fz) are self-explanatory. Note that other atom attributes can be used as inputs to this fix by using the "compute property/atom"_compute_property_atom.html command and then specifying an input value from that compute. If a value begins with "c_", a compute ID must follow which has been previously defined in the input script. Computes can generate per-atom or local quantities. See the individual "compute"_compute.html doc page for details. If no bracketed integer is appended, the vector calculated by the compute is used. If a bracketed integer is appended, the Ith column of the array calculated by the compute is used. Users can also write code for their own compute styles and "add them to LAMMPS"_Section_modify.html. See the discussion above for how I can be specified with a wildcard asterisk to effectively specify multiple values. If a value begins with "f_", a fix ID must follow which has been previously defined in the input script. Fixes can generate per-atom or local quantities. See the individual "fix"_fix.html doc page for details. Note that some fixes only produce their values on certain timesteps, which must be compatible with when compute reduce references the values, else an error results. If no bracketed integer is appended, the vector calculated by the fix is used. If a bracketed integer is appended, the Ith column of the array calculated by the fix is used. Users can also write code for their own fix style and "add them to LAMMPS"_Section_modify.html. See the discussion above for how I can be specified with a wildcard asterisk to effectively specify multiple values. If a value begins with "v_", a variable name must follow which has been previously defined in the input script. It must be an "atom-style variable"_variable.html. Atom-style variables can reference thermodynamic keywords and various per-atom attributes, or invoke other computes, fixes, or variables when they are evaluated, so this is a very general means of generating per-atom quantities to reduce. :line If the {replace} keyword is used, two indices {vec1} and {vec2} are specified, where each index ranges from 1 to the # of input values. The replace keyword can only be used if the {mode} is {min} or {max}. It works as follows. A min/max is computed as usual on the {vec2} input vector. The index N of that value within {vec2} is also stored. Then, instead of performing a min/max on the {vec1} input vector, the stored index is used to select the Nth element of the {vec1} vector. Thus, for example, if you wish to use this compute to find the bond with maximum stretch, you can do it as follows: compute 1 all property/local batom1 batom2 -compute 2 all bond/local dist -compute 3 all reduce max c_1\[1\] c_1\[2\] c_2 replace 1 3 replace 2 3 +compute 2 all bond/local dist +compute 3 all reduce max c_1\[1\] c_1\[2\] c_2 replace 1 3 replace 2 3 thermo_style custom step temp c_3\[1\] c_3\[2\] c_3\[3\] :pre The first two input values in the compute reduce command are vectors with the IDs of the 2 atoms in each bond, using the "compute property/local"_compute_property_local.html command. The last input value is bond distance, using the "compute bond/local"_compute_bond_local.html command. Instead of taking the max of the two atom ID vectors, which does not yield useful information in this context, the {replace} keywords will extract the atom IDs for the two atoms in the bond of maximum stretch. These atom IDs and the bond stretch will be printed with thermodynamic output. :line If a single input is specified this compute produces a global scalar value. If multiple inputs are specified, this compute produces a global vector of values, the length of which is equal to the number of inputs specified. As discussed below, for the {sum} and {sumsq} modes, the value(s) produced by this compute are all "extensive", meaning their value scales linearly with the number of atoms involved. If normalized values are desired, this compute can be accessed by the "thermo_style custom"_thermo_style.html command with "thermo_modify norm yes"_thermo_modify.html set as an option. Or it can be accessed by a "variable"_variable.html that divides by the appropriate atom count. :line [Output info:] This compute calculates a global scalar if a single input value is specified or a global vector of length N where N is the number of inputs, and which can be accessed by indices 1 to N. These values can be used by any command that uses global scalar or vector values from a compute as input. See "Section 6.15"_Section_howto.html#howto_15 for an overview of LAMMPS output options. All the scalar or vector values calculated by this compute are "intensive", except when the {sum} or {sumsq} modes are used on per-atom or local vectors, in which case the calculated values are "extensive". The scalar or vector values will be in whatever "units"_units.html the quantities being reduced are in. [Restrictions:] none [Related commands:] "compute"_compute.html, "fix"_fix.html, "variable"_variable.html [Default:] none diff --git a/doc/src/compute_rigid_local.txt b/doc/src/compute_rigid_local.txt index 808ef15e6..5cdd58fbc 100644 --- a/doc/src/compute_rigid_local.txt +++ b/doc/src/compute_rigid_local.txt @@ -1,185 +1,185 @@ "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 compute rigid/local command :h3 [Syntax:] compute ID group-ID rigid/local rigidID input1 input2 ... :pre ID, group-ID are documented in "compute"_compute.html command :ulb,l rigid/local = style name of this compute command :l rigidID = ID of fix rigid/small command or one of its variants :l input = one or more rigid body attributes :l possible attributes = id, mol, mass, - x, y, z, xu, yu, zu, ix, iy, iz - vx, vy, vz, fx, fy, fz, + x, y, z, xu, yu, zu, ix, iy, iz + vx, vy, vz, fx, fy, fz, omegax, omegay, omegaz, - angmomx, angmomy, angmomz, - quatw, quati, quatj, quatk, + angmomx, angmomy, angmomz, + quatw, quati, quatj, quatk, tqx, tqy, tqz, inertiax, inertiay, inertiaz id = atom ID of atom within body which owns body properties mol = molecule ID used to define body in "fix rigid/small"_fix_rigid.html command mass = total mass of body x,y,z = center of mass coords of body xu,yu,zu = unwrapped center of mass coords of body ix,iy,iz = box image that the center of mass is in vx,vy,vz = center of mass velocities fx,fy,fz = force of center of mass omegax,omegay,omegaz = angular velocity of body angmomx,angmomy,angmomz = angular momentum of body quatw,quati,quatj,quatk = quaternion components for body tqx,tqy,tqz = torque on body inertiax,inertiay,inertiaz = diagonalized moments of inertia of body :pre :ule [Examples:] compute 1 all rigid/local myRigid mol x y z :pre [Description:] Define a computation that simply stores rigid body attributes for rigid bodies defined by the "fix rigid/small"_fix_rigid.html command or one of its NVE, NVT, NPT, NPH variants. The data is stored as local data so it can be accessed by other "output commands"_Section_howto.html#howto_15 that process local data, such as the "compute reduce"_compute_reduce.html or "dump local"_dump.html commands. Note that this command only works with the "fix rigid/small"_fix_rigid.html command or its variants, not the fix rigid command and its variants. The ID of the "fix rigid/small"_fix_rigid.html command used to define rigid bodies must be specified as {rigidID}. The "fix rigid"_fix_rigid.html command is typically used to define a handful of (potentially very large) rigid bodies. It outputs similar per-body information as this command directly from the fix as global data; see the "fix rigid"_fix_rigid.html doc page for details The local data stored by this command is generated by looping over all the atoms owned on a processor. If the atom is not in the specified {group-ID} or is not part of a rigid body it is skipped. If it is not the atom within a body that is assigned to store the body information it is skipped (only one atom per body is so assigned). If it is the assigned atom, then the info for that body is output. This means that information for N bodies is generated. N may be less than the # of bodies defined by the fix rigid command, if the atoms in some bodies are not in the {group-ID}. NOTE: Which atom in a body owns the body info is determined internal to LAMMPS; it's the one nearest the geometric center of the body. Typically you should avoid this complication, by defining the group associated with this fix to include/exclude entire bodies. Note that as atoms and bodies migrate from processor to processor, there will be no consistent ordering of the entries within the local vector or array from one timestep to the next. Here is an example of how to use this compute to dump rigid body info to a file: compute 1 all rigid/local myRigid mol x y z fx fy fz dump 1 all local 1000 tmp.dump index c_1\[1\] c_1\[2\] c_1\[3\] c_1\[4\] c_1\[5\] c_1\[6\] c_1\[7\] :pre :line This section explains the rigid body attributes that can be specified. The {id} attribute is the atomID of the atom which owns the rigid body, which is assigned by the "fix rigid/small"_fix_rigid.html command. The {mol} attribute is the molecule ID of the rigid body. It should be the molecule ID which all of the atoms in the body belong to, since that is how the "fix rigid/small"_fix_rigid.html command defines its rigid bodies. The {mass} attribute is the total mass of the rigid body. There are two options for outputting the coordinates of the center of mass (COM) of the body. The {x}, {y}, {z} attributes write the COM "unscaled", in the appropriate distance "units"_units.html (Angstroms, sigma, etc). Use {xu}, {yu}, {zu} if you want the COM "unwrapped" by the image flags for each atobody. Unwrapped means that if the body COM has passed thru a periodic boundary one or more times, the value is generated what the COM coordinate would be if it had not been wrapped back into the periodic box. The image flags for the body can be generated directly using the {ix}, {iy}, {iz} attributes. For periodic dimensions, they specify which image of the simulation box the COM is considered to be in. An image of 0 means it is inside the box as defined. A value of 2 means add 2 box lengths to get the true value. A value of -1 means subtract 1 box length to get the true value. LAMMPS updates these flags as the rigid body COMs cross periodic boundaries during the simulation. The {vx}, {vy}, {vz}, {fx}, {fy}, {fz} attributes are components of the COM velocity and force on the COM of the body. The {omegax}, {omegay}, and {omegaz} attributes are the angular velocity componennts of the body around its COM. The {angmomx}, {angmomy}, and {angmomz} attributes are the angular momentum components of the body around its COM. The {quatw}, {quati}, {quatj}, and {quatk} attributes are the components of the 4-vector quaternion representing the orientation of the rigid body. See the "set"_set.html command for an explanation of the quaternion vector. The {angmomx}, {angmomy}, and {angmomz} attributes are the angular momentum components of the body around its COM. The {tqx}, {tqy}, {tqz} attributes are components of the torque acting on the body around its COM. The {inertiax}, {inertiay}, {inertiaz} attributes are components of diagonalized inertia tensor for the body, i.e the 3 moments of inertia for the body around its principal axes, as computed internally by LAMMPS. :line [Output info:] This compute calculates a local vector or local array depending on the number of keywords. The length of the vector or number of rows in the array is the number of rigid bodies. If a single keyword is specified, a local vector is produced. If two or more keywords are specified, a local array is produced where the number of columns = the number of keywords. The vector or array can be accessed by any command that uses local values from a compute as input. See "this section"_Section_howto.html#howto_15 for an overview of LAMMPS output options. The vector or array values will be in whatever "units"_units.html the corresponding attribute is in: id,mol = unitless mass = mass units x,y,z and xy,yu,zu = distance units vx,vy,vz = velocity units fx,fy,fz = force units omegax,omegay,omegaz = radians/time units angmomx,angmomy,angmomz = mass*distance^2/time units quatw,quati,quatj,quatk = unitless tqx,tqy,tqz = torque units inertiax,inertiay,inertiaz = mass*distance^2 units :ul [Restrictions:] This compute is part of the RIGID 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. [Related commands:] "dump local"_dump.html, "compute reduce"_compute_reduce.html [Default:] none diff --git a/doc/src/compute_stress_atom.txt b/doc/src/compute_stress_atom.txt index 274947843..08e2dd0ab 100644 --- a/doc/src/compute_stress_atom.txt +++ b/doc/src/compute_stress_atom.txt @@ -1,164 +1,164 @@ "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 compute stress/atom command :h3 [Syntax:] compute ID group-ID stress/atom temp-ID keyword ... :pre ID, group-ID are documented in "compute"_compute.html command stress/atom = style name of this compute command temp-ID = ID of compute that calculates temperature, can be NULL if not needed zero or more keywords may be appended keyword = {ke} or {pair} or {bond} or {angle} or {dihedral} or {improper} or {kspace} or {fix} or {virial} :ul [Examples:] compute 1 mobile stress/atom NULL compute 1 mobile stress/atom myRamp compute 1 all stress/atom NULL pair bond :pre [Description:] Define a computation that computes the symmetric per-atom stress tensor for each atom in a group. The tensor for each atom has 6 components and is stored as a 6-element vector in the following order: xx, yy, zz, xy, xz, yz. See the "compute pressure"_compute_pressure.html command if you want the stress tensor (pressure) of the entire system. The stress tensor for atom {I} is given by the following formula, where {a} and {b} take on values x,y,z to generate the 6 components of the symmetric tensor: :c,image(Eqs/stress_tensor.jpg) The first term is a kinetic energy contribution for atom {I}. See details below on how the specified {temp-ID} can affect the velocities used in this calculation. The second term is a pairwise energy contribution where {n} loops over the {Np} neighbors of atom {I}, {r1} and {r2} are the positions of the 2 atoms in the pairwise interaction, and {F1} and {F2} are the forces on the 2 atoms resulting from the pairwise interaction. The third term is a bond contribution of similar form for the {Nb} bonds which atom {I} is part of. There are similar terms for the {Na} angle, {Nd} dihedral, and {Ni} improper interactions atom {I} is part of. There is also a term for the KSpace contribution from long-range Coulombic interactions, if defined. Finally, there is a term for the {Nf} "fixes"_fix.html that apply internal constraint forces to atom {I}. Currently, only the "fix shake"_fix_shake.html and "fix rigid"_fix_rigid.html commands contribute to this term. As the coefficients in the formula imply, a virial contribution produced by a small set of atoms (e.g. 4 atoms in a dihedral or 3 atoms in a Tersoff 3-body interaction) is assigned in equal portions to each atom in the set. E.g. 1/4 of the dihedral virial to each of the 4 atoms, or 1/3 of the fix virial due to SHAKE constraints applied to atoms in a a water molecule via the "fix shake"_fix_shake.html command. If no extra keywords are listed, all of the terms in this formula are included in the per-atom stress tensor. If any extra keywords are listed, only those terms are summed to compute the tensor. The {virial} keyword means include all terms except the kinetic energy {ke}. Note that the stress for each atom is due to its interaction with all other atoms in the simulation, not just with other atoms in the group. Details of how LAMMPS computes the virial for individual atoms for either pairwise or manybody potentials, and including the effects of periodic boundary conditions is discussed in "(Thompson)"_#Thompson. The basic idea for manybody potentials is to treat each component of the force computation between a small cluster of atoms in the same manner as in the formula above for bond, angle, dihedral, etc interactions. Namely the quantity R dot F is summed over the atoms in the interaction, with the R vectors unwrapped by periodic boundaries so that the cluster of atoms is close together. The total contribution for the cluster interaction is divided evenly among those atoms. The "dihedral_style charmm"_dihedral_charmm.html style calculates pairwise interactions between 1-4 atoms. The virial contribution of these terms is included in the pair virial, not the dihedral virial. The KSpace contribution is calculated using the method in "(Heyes)"_#Heyes for the Ewald method and by the methodology described in "(Sirk)"_#Sirk for PPPM. The choice of KSpace solver is specified by the "kspace_style pppm"_kspace_style.html command. Note that for PPPM, the calcluation requires 6 extra FFTs each timestep that per-atom stress is calculated. Thus it can significantly increase the cost of the PPPM calculation if it is needed on a large fraction of the simulation timesteps. The {temp-ID} argument can be used to affect the per-atom velocities used in the kinetic energy contribution to the total stress. If the kinetic energy is not included in the stress, than the temperature compute is not used and can be specified as NULL. If the kinetic energy is included and you wish to use atom velocities as-is, then {temp-ID} can also be specified as NULL. If desired, the specified temperature compute can be one that subtracts off a bias to leave each atom with only a thermal velocity to use in the formula above, e.g. by subtracting a background streaming velocity. See the doc pages for individual "compute commands"_compute.html to determine which ones include a bias. :line Note that as defined in the formula, per-atom stress is the negative of the per-atom pressure tensor. It is also really a stress*volume formulation, meaning the computed quantity is in units of pressure*volume. It would need to be divided by a per-atom volume to have units of stress (pressure), but an individual atom's volume is not well defined or easy to compute in a deformed solid or a liquid. See the "compute voronoi/atom"_compute_voronoi_atom.html command for one possible way to estimate a per-atom volume. Thus, if the diagonal components of the per-atom stress tensor are summed for all atoms in the system and the sum is divided by dV, where d = dimension and V is the volume of the system, the result should be -P, where P is the total pressure of the system. These lines in an input script for a 3d system should yield that result. I.e. the last 2 columns of thermo output will be the same: -compute peratom all stress/atom NULL -compute p all reduce sum c_peratom\[1\] c_peratom\[2\] c_peratom\[3\] -variable press equal -(c_p\[1\]+c_p\[2\]+c_p\[3\])/(3*vol) -thermo_style custom step temp etotal press v_press :pre +compute peratom all stress/atom NULL +compute p all reduce sum c_peratom\[1\] c_peratom\[2\] c_peratom\[3\] +variable press equal -(c_p\[1\]+c_p\[2\]+c_p\[3\])/(3*vol) +thermo_style custom step temp etotal press v_press :pre [Output info:] This compute calculates a per-atom array with 6 columns, which can be accessed by indices 1-6 by any command that uses per-atom values from a compute as input. See "Section 6.15"_Section_howto.html#howto_15 for an overview of LAMMPS output options. The per-atom array values will be in pressure*volume "units"_units.html as discussed above. [Restrictions:] none [Related commands:] "compute pe"_compute_pe.html, "compute pressure"_compute_pressure.html [Default:] none :line :link(Heyes) [(Heyes)] Heyes, Phys Rev B 49, 755 (1994), :link(Sirk) [(Sirk)] Sirk, Moore, Brown, J Chem Phys, 138, 064505 (2013). :link(Thompson) [(Thompson)] Thompson, Plimpton, Mattson, J Chem Phys, 131, 154107 (2009). diff --git a/doc/src/compute_temp_asphere.txt b/doc/src/compute_temp_asphere.txt old mode 100755 new mode 100644 diff --git a/doc/src/compute_temp_body.txt b/doc/src/compute_temp_body.txt old mode 100755 new mode 100644 diff --git a/doc/src/compute_temp_sphere.txt b/doc/src/compute_temp_sphere.txt old mode 100755 new mode 100644 diff --git a/doc/src/create_atoms.txt b/doc/src/create_atoms.txt index 7f9b253ab..ec7a6f4d8 100644 --- a/doc/src/create_atoms.txt +++ b/doc/src/create_atoms.txt @@ -1,318 +1,318 @@ "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 create_atoms command :h3 [Syntax:] create_atoms type style args keyword values ... :pre type = atom type (1-Ntypes) of atoms to create (offset for molecule creation) :ulb,l style = {box} or {region} or {single} or {random} :l {box} args = none {region} args = region-ID region-ID = particles will only be created if contained in the region {single} args = x y z x,y,z = coordinates of a single particle (distance units) {random} args = N seed region-ID N = number of particles to create seed = random # seed (positive integer) region-ID = create atoms within this region, use NULL for entire simulation box :pre zero or more keyword/value pairs may be appended :l keyword = {mol} or {basis} or {remap} or {var} or {set} or {units} :l {mol} value = template-ID seed template-ID = ID of molecule template specified in a separate "molecule"_molecule.html command seed = random # seed (positive integer) {basis} values = M itype M = which basis atom itype = atom type (1-N) to assign to this basis atom {remap} value = {yes} or {no} {var} value = name = variable name to evaluate for test of atom creation {set} values = dim name dim = {x} or {y} or {z} name = name of variable to set with x, y, or z atom position {rotate} values = Rx Ry Rz theta Rx,Ry,Rz = rotation vector for single molecule theta = rotation angle for single molecule (degrees) {units} value = {lattice} or {box} {lattice} = the geometry is defined in lattice units {box} = the geometry is defined in simulation box units :pre :ule [Examples:] create_atoms 1 box create_atoms 3 region regsphere basis 2 3 create_atoms 3 single 0 0 5 create_atoms 1 box var v set x xpos set y ypos :pre [Description:] This command creates atoms (or molecules) on a lattice, or a single atom (or molecule), or a random collection of atoms (or molecules), as an alternative to reading in their coordinates explicitly via a "read_data"_read_data.html or "read_restart"_read_restart.html command. A simulation box must already exist, which is typically created via the "create_box"_create_box.html command. Before using this command, a lattice must also be defined using the "lattice"_lattice.html command, unless you specify the {single} style with units = box or the {random} style. For the remainder of this doc page, a created atom or molecule is referred to as a "particle". If created particles are individual atoms, they are assigned the specified atom {type}, though this can be altered via the {basis} keyword as discussed below. If molecules are being created, the type of each atom in the created molecule is specified in the file read by the "molecule"_molecule.html command, and those values are added to the specified atom {type}. E.g. if {type} = 2, and the file specifies atom types 1,2,3, then each created molecule will have atom types 3,4,5. For the {box} style, the create_atoms command fills the entire simulation box with particles on the lattice. If your simulation box is periodic, you should insure its size is a multiple of the lattice spacings, to avoid unwanted atom overlaps at the box boundaries. If your box is periodic and a multiple of the lattice spacing in a particular dimension, LAMMPS is careful to put exactly one particle at the boundary (on either side of the box), not zero or two. For the {region} style, a geometric volume is filled with particles on the lattice. This volume what is inside the simulation box and is also consistent with the region volume. See the "region"_region.html command for details. Note that a region can be specified so that its "volume" is either inside or outside a geometric boundary. Also note that if your region is the same size as a periodic simulation box (in some dimension), LAMMPS does not implement the same logic described above as for the {box} style, to insure exactly one particle at periodic boundaries. if this is what you desire, you should either use the {box} style, or tweak the region size to get precisely the particles you want. For the {single} style, a single particle is added to the system at the specified coordinates. This can be useful for debugging purposes or to create a tiny system with a handful of particles at specified positions. For the {random} style, N particles are added to the system at randomly generated coordinates, which can be useful for generating an amorphous system. The particles are created one by one using the speficied random number {seed}, resulting in the same set of particles coordinates, independent of how many processors are being used in the simulation. If the {region-ID} argument is specified as NULL, then the created particles will be anywhere in the simulation box. If a {region-ID} is specified, a geometric volume is filled which is both inside the simulation box and is also consistent with the region volume. See the "region"_region.html command for details. Note that a region can be specified so that its "volume" is either inside or outside a geometric boundary. NOTE: Particles generated by the {random} style will typically be highly overlapped which will cause many interatomic potentials to compute large energies and forces. Thus you should either perform an "energy minimization"_minimize.html or run dynamics with "fix nve/limit"_fix_nve_limit.html to equilibrate such a system, before running normal dynamics. Note that this command adds particles to those that already exist. This means it can be used to add particles to a system previously read in from a data or restart file. Or the create_atoms command can be used multiple times, to add multiple sets of particles to the simulation. For example, grain boundaries can be created, by interleaving create_atoms with "lattice"_lattice.html commands specifying different orientations. By using the create_atoms command in conjunction with the "delete_atoms"_delete_atoms.html command, reasonably complex geometries can be created, or a protein can be solvated with a surrounding box of water molecules. In all these cases, care should be taken to insure that new atoms do not overlap existing atoms inappropriately, especially if molecules are being added. The "delete_atoms"_delete_atoms.html command can be used to remove overlapping atoms or molecules. :line Individual atoms are inserted by this command, unless the {mol} keyword is used. It specifies a {template-ID} previously defined using the "molecule"_molecule.html command, which reads a file that defines the molecule. The coordinates, atom types, charges, etc, as well as any bond/angle/etc and special neighbor information for the molecule can be specified in the molecule file. See the "molecule"_molecule.html command for details. The only settings required to be in this file are the coordinates and types of atoms in the molecule. Using a lattice to add molecules, e.g. via the {box} or {region} or {single} styles, is exactly the same as adding atoms on lattice points, except that entire molecules are added at each point, i.e. on the point defined by each basis atom in the unit cell as it tiles the simulation box or region. This is done by placing the geometric center of the molecule at the lattice point, and giving the molecule a random orientation about the point. The random {seed} specified with the {mol} keyword is used for this operation, and the random numbers generated by each processor are different. This means the coordinates of individual atoms (in the molecules) will be different when running on different numbers of processors, unlike when atoms are being created in parallel. Also note that because of the random rotations, it may be important to use a lattice with a large enough spacing that adjacent molecules will not overlap, regardless of their relative orientations. NOTE: If the "create_box"_create_box.html command is used to create the simulation box, followed by the create_atoms command with its {mol} option for adding molecules, then you typically need to use the optional keywords allowed by the "create_box"_create_box.html command for extra bonds (angles,etc) or extra special neighbors. This is because by default, the "create_box"_create_box.html command sets up a non-molecular system which doesn't allow molecules to be added. :line This is the meaning of the other allowed keywords. The {basis} keyword is only used when atoms (not molecules) are being created. It specifies an atom type that will be assigned to specific basis atoms as they are created. See the "lattice"_lattice.html command for specifics on how basis atoms are defined for the unit cell of the lattice. By default, all created atoms are assigned the argument {type} as their atom type. The {remap} keyword only applies to the {single} style. If it is set to {yes}, then if the specified position is outside the simulation box, it will mapped back into the box, assuming the relevant dimensions are periodic. If it is set to {no}, no remapping is done and no particle is created if its position is outside the box. The {var} and {set} keywords can be used together to provide a criterion for accepting or rejecting the addition of an individual atom, based on its coordinates. The {name} specified for the {var} keyword is the name of an "equal-style variable"_variable.html which should evaluate to a zero or non-zero value based on one or two or three variables which will store the x, y, or z coordinates of an atom (one variable per coordinate). If used, these other variables must be "internal-style variables"_variable.html defined in the input script; their initial numeric value can be anything. They must be internal-style variables, because this command resets their values directly. The {set} keyword is used to identify the names of these other variables, one variable for the x-coordinate of a created atom, one for y, and one for z. When an atom is created, its x,y,z coordinates become the values for any {set} variable that is defined. The {var} variable is then evaluated. If the returned value is 0.0, the atom is not created. If it is non-zero, the atom is created. As an example, these commands can be used in a 2d simulation, to create a sinusoidal surface. Note that the surface is "rough" due to individual lattice points being "above" or "below" the mathematical expression for the sinusoidal curve. If a finer lattice were used, the sinusoid would appear to be "smoother". Also note the use of the "xlat" and "ylat" "thermo_style"_thermo_style.html keywords which converts lattice spacings to distance. Click on the image for a larger version. variable x equal 100 variable y equal 25 -lattice hex 0.8442 -region box block 0 $x 0 $y -0.5 0.5 -create_box 1 box :pre +lattice hex 0.8442 +region box block 0 $x 0 $y -0.5 0.5 +create_box 1 box :pre variable xx equal 0.0 variable yy equal 0.0 variable v equal "(0.2*v_y*ylat * cos(v_xx/xlat * 2.0*PI*4.0/v_x) + 0.5*v_y*ylat - v_yy) > 0.0" -create_atoms 1 box var v set x xx set y yy :pre +create_atoms 1 box var v set x xx set y yy :pre :c,image(JPG/sinusoid_small.jpg,JPG/sinusoid.jpg) The {rotate} keyword can be used with the {single} style, when adding a single molecule to specify the orientation at which the molecule is inserted. The axis of rotation is determined by the rotation vector (Rx,Ry,Rz) that goes through the insertion point. The specified {theta} determines the angle of rotation around that axis. Note that the direction of rotation for the atoms around the rotation axis is consistent with the right-hand rule: if your right-hand's thumb points along {R}, then your fingers wrap around the axis in the direction of rotation. The {units} keyword determines the meaning of the distance units used to specify the coordinates of the one particle created by the {single} style. A {box} value selects standard distance units as defined by the "units"_units.html command, e.g. Angstroms for units = real or metal. A {lattice} value means the distance units are in lattice spacings. :line Atom IDs are assigned to created atoms in the following way. The collection of created atoms are assigned consecutive IDs that start immediately following the largest atom ID existing before the create_atoms command was invoked. When a simulation is performed on different numbers of processors, there is no guarantee a particular created atom will be assigned the same ID. If molecules are being created, molecule IDs are assigned to created molecules in a similar fashion. Aside from their ID, atom type, and xyz position, other properties of created atoms are set to default values, depending on which quantities are defined by the chosen "atom style"_atom_style.html. See the "atom style"_atom_style.html command for more details. See the "set"_set.html and "velocity"_velocity.html commands for info on how to change these values. charge = 0.0 dipole moment magnitude = 0.0 diameter = 1.0 shape = 0.0 0.0 0.0 density = 1.0 volume = 1.0 velocity = 0.0 0.0 0.0 angular velocity = 0.0 0.0 0.0 angular momentum = 0.0 0.0 0.0 quaternion = (1,0,0,0) bonds, angles, dihedrals, impropers = none :ul If molecules are being created, these defaults can be overridden by values specified in the file read by the "molecule"_molecule.html command. E.g. the file typically defines bonds (angles,etc) between atoms in the molecule, and can optionally define charges on each atom. Note that the {sphere} atom style sets the default particle diameter to 1.0 as well as the density. This means the mass for the particle is not 1.0, but is PI/6 * diameter^3 = 0.5236. Note that the {ellipsoid} atom style sets the default particle shape to (0.0 0.0 0.0) and the density to 1.0 which means it is a point particle, not an ellipsoid, and has a mass of 1.0. Note that the {peri} style sets the default volume and density to 1.0 and thus also set the mass for the particle to 1.0. The "set"_set.html command can be used to override many of these default settings. :line [Restrictions:] An "atom_style"_atom_style.html must be previously defined to use this command. A rotation vector specified for a single molecule must be in the z-direction for a 2d model. [Related commands:] "lattice"_lattice.html, "region"_region.html, "create_box"_create_box.html, "read_data"_read_data.html, "read_restart"_read_restart.html [Default:] The default for the {basis} keyword is that all created atoms are assigned the argument {type} as their atom type (when single atoms are being created). The other defaults are {remap} = no, {rotate} = random, and {units} = lattice. diff --git a/doc/src/dump.txt b/doc/src/dump.txt index e384d2182..767e791d7 100644 --- a/doc/src/dump.txt +++ b/doc/src/dump.txt @@ -1,678 +1,678 @@ "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 dump command :h3 "dump custom/vtk"_dump_custom_vtk.html command :h3 "dump h5md"_dump_h5md.html command :h3 "dump image"_dump_image.html command :h3 "dump movie"_dump_image.html command :h3 "dump molfile"_dump_molfile.html command :h3 [Syntax:] dump ID group-ID style N file args :pre ID = user-assigned name for the dump :ulb,l group-ID = ID of the group of atoms to be dumped :l style = {atom} or {atom/gz} or {atom/mpiio} or {cfg} or {cfg/gz} or {cfg/mpiio} or {dcd} or {xtc} or {xyz} or {xyz/gz} or {xyz/mpiio} or {h5md} or {image} or {movie} or {molfile} or {local} or {custom} or {custom/gz} or {custom/mpiio} :l N = dump every this many timesteps :l file = name of file to write dump info to :l args = list of arguments for a particular style :l {atom} args = none {atom/gz} args = none {atom/mpiio} args = none {cfg} args = same as {custom} args, see below {cfg/gz} args = same as {custom} args, see below {cfg/mpiio} args = same as {custom} args, see below {dcd} args = none {xtc} args = none {xyz} args = none :pre {xyz/gz} args = none :pre {xyz/mpiio} args = none :pre {custom/vtk} args = similar to custom args below, discussed on "dump custom/vtk"_dump_custom_vtk.html doc page :pre {h5md} args = discussed on "dump h5md"_dump_h5md.html doc page :pre {image} args = discussed on "dump image"_dump_image.html doc page :pre {movie} args = discussed on "dump image"_dump_image.html doc page :pre {molfile} args = discussed on "dump molfile"_dump_molfile.html doc page :pre {local} args = list of local attributes possible attributes = index, c_ID, c_ID\[I\], f_ID, f_ID\[I\] index = enumeration of local values c_ID = local vector calculated by a compute with ID c_ID\[I\] = Ith column of local array calculated by a compute with ID, I can include wildcard (see below) f_ID = local vector calculated by a fix with ID f_ID\[I\] = Ith column of local array calculated by a fix with ID, I can include wildcard (see below) :pre {custom} or {custom/gz} or {custom/mpiio} args = list of atom attributes possible attributes = id, mol, proc, procp1, type, element, mass, - x, y, z, xs, ys, zs, xu, yu, zu, - xsu, ysu, zsu, ix, iy, iz, - vx, vy, vz, fx, fy, fz, + x, y, z, xs, ys, zs, xu, yu, zu, + xsu, ysu, zsu, ix, iy, iz, + vx, vy, vz, fx, fy, fz, q, mux, muy, muz, mu, radius, diameter, omegax, omegay, omegaz, - angmomx, angmomy, angmomz, tqx, tqy, tqz, - c_ID, c_ID\[N\], f_ID, f_ID\[N\], v_name :pre + angmomx, angmomy, angmomz, tqx, tqy, tqz, + c_ID, c_ID\[N\], f_ID, f_ID\[N\], v_name :pre id = atom ID mol = molecule ID proc = ID of processor that owns atom procp1 = ID+1 of processor that owns atom type = atom type element = name of atom element, as defined by "dump_modify"_dump_modify.html command mass = atom mass x,y,z = unscaled atom coordinates xs,ys,zs = scaled atom coordinates xu,yu,zu = unwrapped atom coordinates xsu,ysu,zsu = scaled unwrapped atom coordinates ix,iy,iz = box image that the atom is in vx,vy,vz = atom velocities fx,fy,fz = forces on atoms q = atom charge mux,muy,muz = orientation of dipole moment of atom mu = magnitude of dipole moment of atom radius,diameter = radius,diameter of spherical particle omegax,omegay,omegaz = angular velocity of spherical particle angmomx,angmomy,angmomz = angular momentum of aspherical particle tqx,tqy,tqz = torque on finite-size particles c_ID = per-atom vector calculated by a compute with ID c_ID\[I\] = Ith column of per-atom array calculated by a compute with ID, I can include wildcard (see below) f_ID = per-atom vector calculated by a fix with ID f_ID\[I\] = Ith column of per-atom array calculated by a fix with ID, I can include wildcard (see below) v_name = per-atom vector calculated by an atom-style variable with name d_name = per-atom floating point vector with name, managed by fix property/atom i_name = per-atom integer vector with name, managed by fix property/atom :pre :ule [Examples:] dump myDump all atom 100 dump.atom dump myDump all atom/mpiio 100 dump.atom.mpiio dump myDump all atom/gz 100 dump.atom.gz dump 2 subgroup atom 50 dump.run.bin dump 2 subgroup atom 50 dump.run.mpiio.bin dump 4a all custom 100 dump.myforce.* id type x y vx fx dump 4b flow custom 100 dump.%.myforce id type c_myF\[3\] v_ke dump 4b flow custom 100 dump.%.myforce id type c_myF\[*\] v_ke dump 2 inner cfg 10 dump.snap.*.cfg mass type xs ys zs vx vy vz dump snap all cfg 100 dump.config.*.cfg mass type xs ys zs id type c_Stress\[2\] dump 1 all xtc 1000 file.xtc :pre [Description:] Dump a snapshot of atom quantities to one or more files every N timesteps in one of several styles. The {image} and {movie} styles are the exception: the {image} style renders a JPG, PNG, or PPM image file of the atom configuration every N timesteps while the {movie} style combines and compresses them into a movie file; both are discussed in detail on the "dump image"_dump_image.html doc page. The timesteps on which dump output is written can also be controlled by a variable. See the "dump_modify every"_dump_modify.html command. Only information for atoms in the specified group is dumped. The "dump_modify thresh and region"_dump_modify.html commands can also alter what atoms are included. Not all styles support all these options; see details below. As described below, the filename determines the kind of output (text or binary or gzipped, one big file or one per timestep, one big file or multiple smaller files). NOTE: Because periodic boundary conditions are enforced only on timesteps when neighbor lists are rebuilt, the coordinates of an atom written to a dump file may be slightly outside the simulation box. Re-neighbor timesteps will not typically coincide with the timesteps dump snapshots are written. See the "dump_modify pbc"_dump_modify.html command if you with to force coordinates to be strictly inside the simulation box. NOTE: Unless the "dump_modify sort"_dump_modify.html option is invoked, the lines of atom information written to dump files (typically one line per atom) will be in an indeterminate order for each snapshot. This is even true when running on a single processor, if the "atom_modify sort"_atom_modify.html option is on, which it is by default. In this case atoms are re-ordered periodically during a simulation, due to spatial sorting. It is also true when running in parallel, because data for a single snapshot is collected from multiple processors, each of which owns a subset of the atoms. For the {atom}, {custom}, {cfg}, and {local} styles, sorting is off by default. For the {dcd}, {xtc}, {xyz}, and {molfile} styles, sorting by atom ID is on by default. See the "dump_modify"_dump_modify.html doc page for details. The {atom/gz}, {cfg/gz}, {custom/gz}, and {xyz/gz} styles are identical in command syntax to the corresponding styles without "gz", however, they generate compressed files using the zlib library. Thus the filename suffix ".gz" is mandatory. This is an alternative approach to writing compressed files via a pipe, as done by the regular dump styles, which may be required on clusters where the interface to the high-speed network disallows using the fork() library call (which is needed for a pipe). For the remainder of this doc page, you should thus consider the {atom} and {atom/gz} styles (etc) to be inter-changeable, with the exception of the required filename suffix. As explained below, the {atom/mpiio}, {cfg/mpiio}, {custom/mpiio}, and {xyz/mpiio} styles are identical in command syntax and in the format of the dump files they create, to the corresponding styles without "mpiio", except the single dump file they produce is written in parallel via the MPI-IO library. For the remainder of this doc page, you should thus consider the {atom} and {atom/mpiio} styles (etc) to be inter-changeable. The one exception is how the filename is specified for the MPI-IO styles, as explained below. The precision of values output to text-based dump files can be controlled by the "dump_modify format"_dump_modify.html command and its options. :line The {style} keyword determines what atom quantities are written to the file and in what format. Settings made via the "dump_modify"_dump_modify.html command can also alter the format of individual values and the file itself. The {atom}, {local}, and {custom} styles create files in a simple text format that is self-explanatory when viewing a dump file. Many of the LAMMPS "post-processing tools"_Section_tools.html, including "Pizza.py"_http://www.sandia.gov/~sjplimp/pizza.html, work with this format, as does the "rerun"_rerun.html command. For post-processing purposes the {atom}, {local}, and {custom} text files are self-describing in the following sense. The dimensions of the simulation box are included in each snapshot. For an orthogonal simulation box this information is is formatted as: ITEM: BOX BOUNDS xx yy zz xlo xhi ylo yhi zlo zhi :pre where xlo,xhi are the maximum extents of the simulation box in the x-dimension, and similarly for y and z. The "xx yy zz" represent 6 characters that encode the style of boundary for each of the 6 simulation box boundaries (xlo,xhi and ylo,yhi and zlo,zhi). Each of the 6 characters is either p = periodic, f = fixed, s = shrink wrap, or m = shrink wrapped with a minimum value. See the "boundary"_boundary.html command for details. For triclinic simulation boxes (non-orthogonal), an orthogonal bounding box which encloses the triclinic simulation box is output, along with the 3 tilt factors (xy, xz, yz) of the triclinic box, formatted as follows: ITEM: BOX BOUNDS xy xz yz xx yy zz xlo_bound xhi_bound xy ylo_bound yhi_bound xz zlo_bound zhi_bound yz :pre The presence of the text "xy xz yz" in the ITEM line indicates that the 3 tilt factors will be included on each of the 3 following lines. This bounding box is convenient for many visualization programs. The meaning of the 6 character flags for "xx yy zz" is the same as above. Note that the first two numbers on each line are now xlo_bound instead of xlo, etc, since they repesent a bounding box. See "this section"_Section_howto.html#howto_12 of the doc pages for a geometric description of triclinic boxes, as defined by LAMMPS, simple formulas for how the 6 bounding box extents (xlo_bound,xhi_bound,etc) are calculated from the triclinic parameters, and how to transform those parameters to and from other commonly used triclinic representations. The "ITEM: ATOMS" line in each snapshot lists column descriptors for the per-atom lines that follow. For example, the descriptors would be "id type xs ys zs" for the default {atom} style, and would be the atom attributes you specify in the dump command for the {custom} style. For style {atom}, atom coordinates are written to the file, along with the atom ID and atom type. By default, atom coords are written in a scaled format (from 0 to 1). I.e. an x value of 0.25 means the atom is at a location 1/4 of the distance from xlo to xhi of the box boundaries. The format can be changed to unscaled coords via the "dump_modify"_dump_modify.html settings. Image flags can also be added for each atom via dump_modify. Style {custom} allows you to specify a list of atom attributes to be written to the dump file for each atom. Possible attributes are listed above and will appear in the order specified. You cannot specify a quantity that is not defined for a particular simulation - such as {q} for atom style {bond}, since that atom style doesn't assign charges. Dumps occur at the very end of a timestep, so atom attributes will include effects due to fixes that are applied during the timestep. An explanation of the possible dump custom attributes is given below. For style {local}, local output generated by "computes"_compute.html and "fixes"_fix.html is used to generate lines of output that is written to the dump file. This local data is typically calculated by each processor based on the atoms it owns, but there may be zero or more entities per atom, e.g. a list of bond distances. An explanation of the possible dump local attributes is given below. Note that by using input from the "compute property/local"_compute_property_local.html command with dump local, it is possible to generate information on bonds, angles, etc that can be cut and pasted directly into a data file read by the "read_data"_read_data.html command. Style {cfg} has the same command syntax as style {custom} and writes extended CFG format files, as used by the "AtomEye"_http://mt.seas.upenn.edu/Archive/Graphics/A visualization package. Since the extended CFG format uses a single snapshot of the system per file, a wildcard "*" must be included in the filename, as discussed below. The list of atom attributes for style {cfg} must begin with either "mass type xs ys zs" or "mass type xsu ysu zsu" since these quantities are needed to write the CFG files in the appropriate format (though the "mass" and "type" fields do not appear explicitly in the file). Any remaining attributes will be stored as "auxiliary properties" in the CFG files. Note that you will typically want to use the "dump_modify element"_dump_modify.html command with CFG-formatted files, to associate element names with atom types, so that AtomEye can render atoms appropriately. When unwrapped coordinates {xsu}, {ysu}, and {zsu} are requested, the nominal AtomEye periodic cell dimensions are expanded by a large factor UNWRAPEXPAND = 10.0, which ensures atoms that are displayed correctly for up to UNWRAPEXPAND/2 periodic boundary crossings in any direction. Beyond this, AtomEye will rewrap the unwrapped coordinates. The expansion causes the atoms to be drawn farther away from the viewer, but it is easy to zoom the atoms closer, and the interatomic distances are unaffected. The {dcd} style writes DCD files, a standard atomic trajectory format used by the CHARMM, NAMD, and XPlor molecular dynamics packages. DCD files are binary and thus may not be portable to different machines. The number of atoms per snapshot cannot change with the {dcd} style. The {unwrap} option of the "dump_modify"_dump_modify.html command allows DCD coordinates to be written "unwrapped" by the image flags for each atom. Unwrapped means that if the atom has passed through a periodic boundary one or more times, the value is printed for what the coordinate would be if it had not been wrapped back into the periodic box. Note that these coordinates may thus be far outside the box size stored with the snapshot. The {xtc} style writes XTC files, a compressed trajectory format used by the GROMACS molecular dynamics package, and described "here"_http://manual.gromacs.org/current/online/xtc.html. The precision used in XTC files can be adjusted via the "dump_modify"_dump_modify.html command. The default value of 1000 means that coordinates are stored to 1/1000 nanometer accuracy. XTC files are portable binary files written in the NFS XDR data format, so that any machine which supports XDR should be able to read them. The number of atoms per snapshot cannot change with the {xtc} style. The {unwrap} option of the "dump_modify"_dump_modify.html command allows XTC coordinates to be written "unwrapped" by the image flags for each atom. Unwrapped means that if the atom has passed thru a periodic boundary one or more times, the value is printed for what the coordinate would be if it had not been wrapped back into the periodic box. Note that these coordinates may thus be far outside the box size stored with the snapshot. The {xyz} style writes XYZ files, which is a simple text-based coordinate format that many codes can read. Specifically it has a line with the number of atoms, then a comment line that is usually ignored followed by one line per atom with the atom type and the x-, y-, and z-coordinate of that atom. You can use the "dump_modify element"_dump_modify.html option to change the output from using the (numerical) atom type to an element name (or some other label). This will help many visualization programs to guess bonds and colors. Note that {atom}, {custom}, {dcd}, {xtc}, and {xyz} style dump files can be read directly by "VMD"_http://www.ks.uiuc.edu/Research/vmd, a popular molecular viewing program. See "Section 9"_Section_tools.html#vmd of the manual and the tools/lmp2vmd/README.txt file for more information about support in VMD for reading and visualizing LAMMPS dump files. :line Dumps are performed on timesteps that are a multiple of N (including timestep 0) and on the last timestep of a minimization if the minimization converges. Note that this means a dump will not be performed on the initial timestep after the dump command is invoked, if the current timestep is not a multiple of N. This behavior can be changed via the "dump_modify first"_dump_modify.html command, which can also be useful if the dump command is invoked after a minimization ended on an arbitrary timestep. N can be changed between runs by using the "dump_modify every"_dump_modify.html command (not allowed for {dcd} style). The "dump_modify every"_dump_modify.html command also allows a variable to be used to determine the sequence of timesteps on which dump files are written. In this mode a dump on the first timestep of a run will also not be written unless the "dump_modify first"_dump_modify.html command is used. The specified filename determines how the dump file(s) is written. The default is to write one large text file, which is opened when the dump command is invoked and closed when an "undump"_undump.html command is used or when LAMMPS exits. For the {dcd} and {xtc} styles, this is a single large binary file. Dump filenames can contain two wildcard characters. If a "*" character appears in the filename, then one file per snapshot is written and the "*" character is replaced with the timestep value. For example, tmp.dump.* becomes tmp.dump.0, tmp.dump.10000, tmp.dump.20000, etc. This option is not available for the {dcd} and {xtc} styles. Note that the "dump_modify pad"_dump_modify.html command can be used to insure all timestep numbers are the same length (e.g. 00010), which can make it easier to read a series of dump files in order with some post-processing tools. If a "%" character appears in the filename, then each of P processors writes a portion of the dump file, and the "%" character is replaced with the processor ID from 0 to P-1. For example, tmp.dump.% becomes tmp.dump.0, tmp.dump.1, ... tmp.dump.P-1, etc. This creates smaller files and can be a fast mode of output on parallel machines that support parallel I/O for output. This option is not available for the {dcd}, {xtc}, and {xyz} styles. By default, P = the number of processors meaning one file per processor, but P can be set to a smaller value via the {nfile} or {fileper} keywords of the "dump_modify"_dump_modify.html command. These options can be the most efficient way of writing out dump files when running on large numbers of processors. Note that using the "*" and "%" characters together can produce a large number of small dump files! For the {atom/mpiio}, {cfg/mpiio}, {custom/mpiio}, and {xyz/mpiio} styles, a single dump file is written in parallel via the MPI-IO library, which is part of the MPI standard for versions 2.0 and above. Using MPI-IO requires two steps. First, build LAMMPS with its MPIIO package installed, e.g. make yes-mpiio # installs the MPIIO package make mpi # build LAMMPS for your platform :pre Second, use a dump filename which contains ".mpiio". Note that it does not have to end in ".mpiio", just contain those characters. Unlike MPI-IO restart files, which must be both written and read using MPI-IO, the dump files produced by these MPI-IO styles are identical in format to the files produced by their non-MPI-IO style counterparts. This means you can write a dump file using MPI-IO and use the "read_dump"_read_dump.html command or perform other post-processing, just as if the dump file was not written using MPI-IO. Note that MPI-IO dump files are one large file which all processors write to. You thus cannot use the "%" wildcard character described above in the filename since that specifies generation of multiple files. You can use the ".bin" suffix described below in an MPI-IO dump file; again this file will be written in parallel and have the same binary format as if it were written without MPI-IO. If the filename ends with ".bin", the dump file (or files, if "*" or "%" is also used) is written in binary format. A binary dump file will be about the same size as a text version, but will typically write out much faster. Of course, when post-processing, you will need to convert it back to text format (see the "binary2txt tool"_Section_tools.html#binary) or write your own code to read the binary file. The format of the binary file can be understood by looking at the tools/binary2txt.cpp file. This option is only available for the {atom} and {custom} styles. If the filename ends with ".gz", the dump file (or files, if "*" or "%" is also used) is written in gzipped format. A gzipped dump file will be about 3x smaller than the text version, but will also take longer to write. This option is not available for the {dcd} and {xtc} styles. :line Note that in the discussion which follows, for styles which can reference values from a compute or fix, like the {custom}, {cfg}, or {local} styles, the bracketed index I can be specified using a wildcard asterisk with the index to effectively specify multiple values. This takes the form "*" or "*n" or "n*" or "m*n". If N = the size of the vector (for {mode} = scalar) or the number of columns in the array (for {mode} = vector), then an asterisk with no numeric values means all indices from 1 to N. A leading asterisk means all indices from 1 to n (inclusive). A trailing asterisk means all indices from n to N (inclusive). A middle asterisk means all indices from m to n (inclusive). Using a wildcard is the same as if the individual columns of the array had been listed one by one. E.g. these 2 dump commands are equivalent, since the "compute stress/atom"_compute_stress_atom.html command creates a per-atom array with 6 columns: compute myPress all stress/atom NULL dump 2 all custom 100 tmp.dump id myPress\[*\] dump 2 all custom 100 tmp.dump id myPress\[1\] myPress\[2\] myPress\[3\] & myPress\[4\] myPress\[5\] myPress\[6\] :pre :line This section explains the local attributes that can be specified as part of the {local} style. The {index} attribute can be used to generate an index number from 1 to N for each line written into the dump file, where N is the total number of local datums from all processors, or lines of output that will appear in the snapshot. Note that because data from different processors depend on what atoms they currently own, and atoms migrate between processor, there is no guarantee that the same index will be used for the same info (e.g. a particular bond) in successive snapshots. The {c_ID} and {c_ID\[I\]} attributes allow local vectors or arrays calculated by a "compute"_compute.html to be output. The ID in the attribute should be replaced by the actual ID of the compute that has been defined previously in the input script. See the "compute"_compute.html command for details. There are computes for calculating local information such as indices, types, and energies for bonds and angles. Note that computes which calculate global or per-atom quantities, as opposed to local quantities, cannot be output in a dump local command. Instead, global quantities can be output by the "thermo_style custom"_thermo_style.html command, and per-atom quantities can be output by the dump custom command. If {c_ID} is used as a attribute, then the local vector calculated by the compute is printed. If {c_ID\[I\]} is used, then I must be in the range from 1-M, which will print the Ith column of the local array with M columns calculated by the compute. See the discussion above for how I can be specified with a wildcard asterisk to effectively specify multiple values. The {f_ID} and {f_ID\[I\]} attributes allow local vectors or arrays calculated by a "fix"_fix.html to be output. The ID in the attribute should be replaced by the actual ID of the fix that has been defined previously in the input script. If {f_ID} is used as a attribute, then the local vector calculated by the fix is printed. If {f_ID\[I\]} is used, then I must be in the range from 1-M, which will print the Ith column of the local with M columns calculated by the fix. See the discussion above for how I can be specified with a wildcard asterisk to effectively specify multiple values. Here is an example of how to dump bond info for a system, including the distance and energy of each bond: compute 1 all property/local batom1 batom2 btype compute 2 all bond/local dist eng dump 1 all local 1000 tmp.dump index c_1\[1\] c_1\[2\] c_1\[3\] c_2\[1\] c_2\[2\] :pre :line This section explains the atom attributes that can be specified as part of the {custom} and {cfg} styles. The {id}, {mol}, {proc}, {procp1}, {type}, {element}, {mass}, {vx}, {vy}, {vz}, {fx}, {fy}, {fz}, {q} attributes are self-explanatory. {Id} is the atom ID. {Mol} is the molecule ID, included in the data file for molecular systems. {Proc} is the ID of the processor (0 to Nprocs-1) that currently owns the atom. {Procp1} is the proc ID+1, which can be convenient in place of a {type} attribute (1 to Ntypes) for coloring atoms in a visualization program. {Type} is the atom type (1 to Ntypes). {Element} is typically the chemical name of an element, which you must assign to each type via the "dump_modify element"_dump_modify.html command. More generally, it can be any string you wish to associated with an atom type. {Mass} is the atom mass. {Vx}, {vy}, {vz}, {fx}, {fy}, {fz}, and {q} are components of atom velocity and force and atomic charge. There are several options for outputting atom coordinates. The {x}, {y}, {z} attributes write atom coordinates "unscaled", in the appropriate distance "units"_units.html (Angstroms, sigma, etc). Use {xs}, {ys}, {zs} if you want the coordinates "scaled" to the box size, so that each value is 0.0 to 1.0. If the simulation box is triclinic (tilted), then all atom coords will still be between 0.0 and 1.0. I.e. actual unscaled (x,y,z) = xs*A + ys*B + zs*C, where (A,B,C) are the non-orthogonal vectors of the simulation box edges, as discussed in "Section 6.12"_Section_howto.html#howto_12. Use {xu}, {yu}, {zu} if you want the coordinates "unwrapped" by the image flags for each atom. Unwrapped means that if the atom has passed thru a periodic boundary one or more times, the value is printed for what the coordinate would be if it had not been wrapped back into the periodic box. Note that using {xu}, {yu}, {zu} means that the coordinate values may be far outside the box bounds printed with the snapshot. Using {xsu}, {ysu}, {zsu} is similar to using {xu}, {yu}, {zu}, except that the unwrapped coordinates are scaled by the box size. Atoms that have passed through a periodic boundary will have the corresponding cooordinate increased or decreased by 1.0. The image flags can be printed directly using the {ix}, {iy}, {iz} attributes. For periodic dimensions, they specify which image of the simulation box the atom is considered to be in. An image of 0 means it is inside the box as defined. A value of 2 means add 2 box lengths to get the true value. A value of -1 means subtract 1 box length to get the true value. LAMMPS updates these flags as atoms cross periodic boundaries during the simulation. The {mux}, {muy}, {muz} attributes are specific to dipolar systems defined with an atom style of {dipole}. They give the orientation of the atom's point dipole moment. The {mu} attribute gives the magnitude of the atom's dipole moment. The {radius} and {diameter} attributes are specific to spherical particles that have a finite size, such as those defined with an atom style of {sphere}. The {omegax}, {omegay}, and {omegaz} attributes are specific to finite-size spherical particles that have an angular velocity. Only certain atom styles, such as {sphere} define this quantity. The {angmomx}, {angmomy}, and {angmomz} attributes are specific to finite-size aspherical particles that have an angular momentum. Only the {ellipsoid} atom style defines this quantity. The {tqx}, {tqy}, {tqz} attributes are for finite-size particles that can sustain a rotational torque due to interactions with other particles. The {c_ID} and {c_ID\[I\]} attributes allow per-atom vectors or arrays calculated by a "compute"_compute.html to be output. The ID in the attribute should be replaced by the actual ID of the compute that has been defined previously in the input script. See the "compute"_compute.html command for details. There are computes for calculating the per-atom energy, stress, centro-symmetry parameter, and coordination number of individual atoms. Note that computes which calculate global or local quantities, as opposed to per-atom quantities, cannot be output in a dump custom command. Instead, global quantities can be output by the "thermo_style custom"_thermo_style.html command, and local quantities can be output by the dump local command. If {c_ID} is used as a attribute, then the per-atom vector calculated by the compute is printed. If {c_ID\[I\]} is used, then I must be in the range from 1-M, which will print the Ith column of the per-atom array with M columns calculated by the compute. See the discussion above for how I can be specified with a wildcard asterisk to effectively specify multiple values. The {f_ID} and {f_ID\[I\]} attributes allow vector or array per-atom quantities calculated by a "fix"_fix.html to be output. The ID in the attribute should be replaced by the actual ID of the fix that has been defined previously in the input script. The "fix ave/atom"_fix_ave_atom.html command is one that calculates per-atom quantities. Since it can time-average per-atom quantities produced by any "compute"_compute.html, "fix"_fix.html, or atom-style "variable"_variable.html, this allows those time-averaged results to be written to a dump file. If {f_ID} is used as a attribute, then the per-atom vector calculated by the fix is printed. If {f_ID\[I\]} is used, then I must be in the range from 1-M, which will print the Ith column of the per-atom array with M columns calculated by the fix. See the discussion above for how I can be specified with a wildcard asterisk to effectively specify multiple values. The {v_name} attribute allows per-atom vectors calculated by a "variable"_variable.html to be output. The name in the attribute should be replaced by the actual name of the variable that has been defined previously in the input script. Only an atom-style variable can be referenced, since it is the only style that generates per-atom values. Variables of style {atom} can reference individual atom attributes, per-atom atom attributes, thermodynamic keywords, or invoke other computes, fixes, or variables when they are evaluated, so this is a very general means of creating quantities to output to a dump file. The {d_name} and {i_name} attributes allow to output custom per atom floating point or integer properties that are managed by "fix property/atom"_fix_property_atom.html. See "Section 10"_Section_modify.html of the manual for information on how to add new compute and fix styles to LAMMPS to calculate per-atom quantities which could then be output into dump files. :line [Restrictions:] To write gzipped dump files, you must either compile LAMMPS with the -DLAMMPS_GZIP option or use the styles from the COMPRESS package - see the "Making LAMMPS"_Section_start.html#start_2 section of the documentation. The {atom/gz}, {cfg/gz}, {custom/gz}, and {xyz/gz} styles are part of the COMPRESS package. They are only enabled if LAMMPS was built with that package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. The {atom/mpiio}, {cfg/mpiio}, {custom/mpiio}, and {xyz/mpiio} styles are part of the MPIIO package. They are only enabled if LAMMPS was built with that package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. The {xtc} style is part of the MISC 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. This is because some machines may not support the low-level XDR data format that XTC files are written with, which will result in a compile-time error when a low-level include file is not found. Putting this style in a package makes it easy to exclude from a LAMMPS build for those machines. However, the MISC package also includes two compatibility header files and associated functions, which should be a suitable substitute on machines that do not have the appropriate native header files. This option can be invoked at build time by adding -DLAMMPS_XDR to the CCFLAGS variable in the appropriate low-level Makefile, e.g. src/MAKE/Makefile.foo. This compatibility mode has been tested successfully on Cray XT3/XT4/XT5 and IBM BlueGene/L machines and should also work on IBM BG/P, and Windows XP/Vista/7 machines. [Related commands:] "dump h5md"_dump_h5md.html, "dump image"_dump_image.html, "dump molfile"_dump_molfile.html, "dump_modify"_dump_modify.html, "undump"_undump.html [Default:] The defaults for the {image} and {movie} styles are listed on the "dump image"_dump_image.html doc page. diff --git a/doc/src/dump_custom_vtk.txt b/doc/src/dump_custom_vtk.txt index 8cb90c083..b84817327 100644 --- a/doc/src/dump_custom_vtk.txt +++ b/doc/src/dump_custom_vtk.txt @@ -1,339 +1,339 @@ "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 dump custom/vtk command :h3 [Syntax:] dump ID group-ID style N file args :pre ID = user-assigned name for the dump :ulb,l group-ID = ID of the group of atoms to be dumped :l style = {custom/vtk} :l N = dump every this many timesteps :l file = name of file to write dump info to :l args = list of arguments for a particular style :l {custom/vtk} args = list of atom attributes possible attributes = id, mol, proc, procp1, type, element, mass, - x, y, z, xs, ys, zs, xu, yu, zu, - xsu, ysu, zsu, ix, iy, iz, - vx, vy, vz, fx, fy, fz, + x, y, z, xs, ys, zs, xu, yu, zu, + xsu, ysu, zsu, ix, iy, iz, + vx, vy, vz, fx, fy, fz, q, mux, muy, muz, mu, radius, diameter, omegax, omegay, omegaz, - angmomx, angmomy, angmomz, tqx, tqy, tqz, - spin, eradius, ervel, erforce, - c_ID, c_ID\[N\], f_ID, f_ID\[N\], v_name :pre + angmomx, angmomy, angmomz, tqx, tqy, tqz, + spin, eradius, ervel, erforce, + c_ID, c_ID\[N\], f_ID, f_ID\[N\], v_name :pre id = atom ID mol = molecule ID proc = ID of processor that owns atom procp1 = ID+1 of processor that owns atom type = atom type element = name of atom element, as defined by "dump_modify"_dump_modify.html command mass = atom mass x,y,z = unscaled atom coordinates xs,ys,zs = scaled atom coordinates xu,yu,zu = unwrapped atom coordinates xsu,ysu,zsu = scaled unwrapped atom coordinates ix,iy,iz = box image that the atom is in vx,vy,vz = atom velocities fx,fy,fz = forces on atoms q = atom charge mux,muy,muz = orientation of dipole moment of atom mu = magnitude of dipole moment of atom radius,diameter = radius,diameter of spherical particle omegax,omegay,omegaz = angular velocity of spherical particle angmomx,angmomy,angmomz = angular momentum of aspherical particle tqx,tqy,tqz = torque on finite-size particles c_ID = per-atom vector calculated by a compute with ID c_ID\[N\] = Nth column of per-atom array calculated by a compute with ID f_ID = per-atom vector calculated by a fix with ID f_ID\[N\] = Nth column of per-atom array calculated by a fix with ID v_name = per-atom vector calculated by an atom-style variable with name :pre :ule [Examples:] dump dmpvtk all custom/vtk 100 dump*.myforce.vtk id type vx fx dump dmpvtp flow custom/vtk 100 dump*.%.displace.vtp id type c_myD\[1\] c_myD\[2\] c_myD\[3\] v_ke dump e_data all custom/vtk 100 dump*.vtu id type spin eradius fx fy fz eforce :pre The style {custom/vtk} is similar to the "custom"_dump.html style but uses the VTK library to write data to VTK simple legacy or XML format depending on the filename extension specified. This can be either {*.vtk} for the legacy format or {*.vtp} and {*.vtu}, respectively, for the XML format; see the "VTK homepage"_http://www.vtk.org/VTK/img/file-formats.pdf for a detailed description of these formats. Since this naming convention conflicts with the way binary output is usually specified (see below), "dump_modify binary"_dump_modify.html allows to set the binary flag for this dump style explicitly. [Description:] Dump a snapshot of atom quantities to one or more files every N timesteps in a format readable by the "VTK visualization toolkit"_http://www.vtk.org or other visualization tools that use it, e.g. "ParaView"_http://www.paraview.org. The timesteps on which dump output is written can also be controlled by a variable; see the "dump_modify every"_dump_modify.html command for details. Only information for atoms in the specified group is dumped. The "dump_modify thresh and region"_dump_modify.html commands can also alter what atoms are included; see details below. As described below, special characters ("*", "%") in the filename determine the kind of output. IMPORTANT NOTE: Because periodic boundary conditions are enforced only on timesteps when neighbor lists are rebuilt, the coordinates of an atom written to a dump file may be slightly outside the simulation box. IMPORTANT NOTE: Unless the "dump_modify sort"_dump_modify.html option is invoked, the lines of atom information written to dump files will be in an indeterminate order for each snapshot. This is even true when running on a single processor, if the "atom_modify sort"_atom_modify.html option is on, which it is by default. In this case atoms are re-ordered periodically during a simulation, due to spatial sorting. It is also true when running in parallel, because data for a single snapshot is collected from multiple processors, each of which owns a subset of the atoms. For the {custom/vtk} style, sorting is off by default. See the "dump_modify"_dump_modify.html doc page for details. :line The dimensions of the simulation box are written to a separate file for each snapshot (either in legacy VTK or XML format depending on the format of the main dump file) with the suffix {_boundingBox} appended to the given dump filename. For an orthogonal simulation box this information is saved as a rectilinear grid (legacy .vtk or .vtr XML format). Triclinic simulation boxes (non-orthogonal) are saved as hexahedrons in either legacy .vtk or .vtu XML format. Style {custom/vtk} allows you to specify a list of atom attributes to be written to the dump file for each atom. Possible attributes are listed above. In contrast to the {custom} style, the attributes are rearranged to ensure correct ordering of vector components (except for computes and fixes - these have to be given in the right order) and duplicate entries are removed. You cannot specify a quantity that is not defined for a particular simulation - such as {q} for atom style {bond}, since that atom style doesn't assign charges. Dumps occur at the very end of a timestep, so atom attributes will include effects due to fixes that are applied during the timestep. An explanation of the possible dump custom/vtk attributes is given below. Since position data is required to write VTK files "x y z" do not have to be specified explicitly. The VTK format uses a single snapshot of the system per file, thus a wildcard "*" must be included in the filename, as discussed below. Otherwise the dump files will get overwritten with the new snapshot each time. :line Dumps are performed on timesteps that are a multiple of N (including timestep 0) and on the last timestep of a minimization if the minimization converges. Note that this means a dump will not be performed on the initial timestep after the dump command is invoked, if the current timestep is not a multiple of N. This behavior can be changed via the "dump_modify first"_dump_modify.html command, which can also be useful if the dump command is invoked after a minimization ended on an arbitrary timestep. N can be changed between runs by using the "dump_modify every"_dump_modify.html command. The "dump_modify every"_dump_modify.html command also allows a variable to be used to determine the sequence of timesteps on which dump files are written. In this mode a dump on the first timestep of a run will also not be written unless the "dump_modify first"_dump_modify.html command is used. Dump filenames can contain two wildcard characters. If a "*" character appears in the filename, then one file per snapshot is written and the "*" character is replaced with the timestep value. For example, tmp.dump*.vtk becomes tmp.dump0.vtk, tmp.dump10000.vtk, tmp.dump20000.vtk, etc. Note that the "dump_modify pad"_dump_modify.html command can be used to insure all timestep numbers are the same length (e.g. 00010), which can make it easier to read a series of dump files in order with some post-processing tools. If a "%" character appears in the filename, then each of P processors writes a portion of the dump file, and the "%" character is replaced with the processor ID from 0 to P-1 preceded by an underscore character. For example, tmp.dump%.vtp becomes tmp.dump_0.vtp, tmp.dump_1.vtp, ... tmp.dump_P-1.vtp, etc. This creates smaller files and can be a fast mode of output on parallel machines that support parallel I/O for output. By default, P = the number of processors meaning one file per processor, but P can be set to a smaller value via the {nfile} or {fileper} keywords of the "dump_modify"_dump_modify.html command. These options can be the most efficient way of writing out dump files when running on large numbers of processors. For the legacy VTK format "%" is ignored and P = 1, i.e., only processor 0 does write files. Note that using the "*" and "%" characters together can produce a large number of small dump files! If {dump_modify binary} is used, the dump file (or files, if "*" or "%" is also used) is written in binary format. A binary dump file will be about the same size as a text version, but will typically write out much faster. :line This section explains the atom attributes that can be specified as part of the {custom/vtk} style. The {id}, {mol}, {proc}, {procp1}, {type}, {element}, {mass}, {vx}, {vy}, {vz}, {fx}, {fy}, {fz}, {q} attributes are self-explanatory. {id} is the atom ID. {mol} is the molecule ID, included in the data file for molecular systems. {type} is the atom type. {element} is typically the chemical name of an element, which you must assign to each type via the "dump_modify element"_dump_modify.html command. More generally, it can be any string you wish to associate with an atom type. {mass} is the atom mass. {vx}, {vy}, {vz}, {fx}, {fy}, {fz}, and {q} are components of atom velocity and force and atomic charge. There are several options for outputting atom coordinates. The {x}, {y}, {z} attributes are used to write atom coordinates "unscaled", in the appropriate distance "units"_units.html (Angstroms, sigma, etc). Additionaly, you can use {xs}, {ys}, {zs} if you want to also save the coordinates "scaled" to the box size, so that each value is 0.0 to 1.0. If the simulation box is triclinic (tilted), then all atom coords will still be between 0.0 and 1.0. Use {xu}, {yu}, {zu} if you want the coordinates "unwrapped" by the image flags for each atom. Unwrapped means that if the atom has passed through a periodic boundary one or more times, the value is printed for what the coordinate would be if it had not been wrapped back into the periodic box. Note that using {xu}, {yu}, {zu} means that the coordinate values may be far outside the box bounds printed with the snapshot. Using {xsu}, {ysu}, {zsu} is similar to using {xu}, {yu}, {zu}, except that the unwrapped coordinates are scaled by the box size. Atoms that have passed through a periodic boundary will have the corresponding cooordinate increased or decreased by 1.0. The image flags can be printed directly using the {ix}, {iy}, {iz} attributes. For periodic dimensions, they specify which image of the simulation box the atom is considered to be in. An image of 0 means it is inside the box as defined. A value of 2 means add 2 box lengths to get the true value. A value of -1 means subtract 1 box length to get the true value. LAMMPS updates these flags as atoms cross periodic boundaries during the simulation. The {mux}, {muy}, {muz} attributes are specific to dipolar systems defined with an atom style of {dipole}. They give the orientation of the atom's point dipole moment. The {mu} attribute gives the magnitude of the atom's dipole moment. The {radius} and {diameter} attributes are specific to spherical particles that have a finite size, such as those defined with an atom style of {sphere}. The {omegax}, {omegay}, and {omegaz} attributes are specific to finite-size spherical particles that have an angular velocity. Only certain atom styles, such as {sphere} define this quantity. The {angmomx}, {angmomy}, and {angmomz} attributes are specific to finite-size aspherical particles that have an angular momentum. Only the {ellipsoid} atom style defines this quantity. The {tqx}, {tqy}, {tqz} attributes are for finite-size particles that can sustain a rotational torque due to interactions with other particles. The {spin}, {eradius}, {ervel}, and {erforce} attributes are for particles that represent nuclei and electrons modeled with the electronic force field (EFF). See "atom_style electron"_atom_style.html and "pair_style eff"_pair_eff.html for more details. The {c_ID} and {c_ID\[N\]} attributes allow per-atom vectors or arrays calculated by a "compute"_compute.html to be output. The ID in the attribute should be replaced by the actual ID of the compute that has been defined previously in the input script. See the "compute"_compute.html command for details. There are computes for calculating the per-atom energy, stress, centro-symmetry parameter, and coordination number of individual atoms. Note that computes which calculate global or local quantities, as opposed to per-atom quantities, cannot be output in a dump custom/vtk command. Instead, global quantities can be output by the "thermo_style custom"_thermo_style.html command, and local quantities can be output by the dump local command. If {c_ID} is used as an attribute, then the per-atom vector calculated by the compute is printed. If {c_ID\[N\]} is used, then N must be in the range from 1-M, which will print the Nth column of the M-length per-atom array calculated by the compute. The {f_ID} and {f_ID\[N\]} attributes allow vector or array per-atom quantities calculated by a "fix"_fix.html to be output. The ID in the attribute should be replaced by the actual ID of the fix that has been defined previously in the input script. The "fix ave/atom"_fix_ave_atom.html command is one that calculates per-atom quantities. Since it can time-average per-atom quantities produced by any "compute"_compute.html, "fix"_fix.html, or atom-style "variable"_variable.html, this allows those time-averaged results to be written to a dump file. If {f_ID} is used as a attribute, then the per-atom vector calculated by the fix is printed. If {f_ID\[N\]} is used, then N must be in the range from 1-M, which will print the Nth column of the M-length per-atom array calculated by the fix. The {v_name} attribute allows per-atom vectors calculated by a "variable"_variable.html to be output. The name in the attribute should be replaced by the actual name of the variable that has been defined previously in the input script. Only an atom-style variable can be referenced, since it is the only style that generates per-atom values. Variables of style {atom} can reference individual atom attributes, per-atom atom attributes, thermodynamic keywords, or invoke other computes, fixes, or variables when they are evaluated, so this is a very general means of creating quantities to output to a dump file. See "Section 10"_Section_modify.html of the manual for information on how to add new compute and fix styles to LAMMPS to calculate per-atom quantities which could then be output into dump files. :line [Restrictions:] The {custom/vtk} style does not support writing of gzipped dump files. The {custom/vtk} dump style is part of the USER-VTK 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. To use this dump style, you also must link to the VTK library. See the info in lib/vtk/README and insure the Makefile.lammps file in that directory is appropriate for your machine. The {custom/vtk} dump style neither supports buffering nor custom format strings. [Related commands:] "dump"_dump.html, "dump image"_dump_image.html, "dump_modify"_dump_modify.html, "undump"_undump.html [Default:] By default, files are written in ASCII format. If the file extension is not one of .vtk, .vtp or .vtu, the legacy VTK file format is used. diff --git a/doc/src/dump_modify.txt b/doc/src/dump_modify.txt index bcb0a4979..1a49917bd 100644 --- a/doc/src/dump_modify.txt +++ b/doc/src/dump_modify.txt @@ -1,999 +1,999 @@ "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 dump_modify command :h3 [Syntax:] dump_modify dump-ID keyword values ... :pre dump-ID = ID of dump to modify :ulb,l one or more keyword/value pairs may be appended :l these keywords apply to various dump styles :l keyword = {append} or {buffer} or {element} or {every} or {fileper} or {first} or {flush} or {format} or {image} or {label} or {nfile} or {pad} or {precision} or {region} or {scale} or {sort} or {thresh} or {unwrap} :l {append} arg = {yes} or {no} {buffer} arg = {yes} or {no} {element} args = E1 E2 ... EN, where N = # of atom types E1,...,EN = element name, e.g. C or Fe or Ga {every} arg = N N = dump every this many timesteps N can be a variable (see below) {fileper} arg = Np Np = write one file for every this many processors {first} arg = {yes} or {no} {format} args = {line} string, {int} string, {float} string, M string, or {none} string = C-style format string M = integer from 1 to N, where N = # of per-atom quantities being output {flush} arg = {yes} or {no} {image} arg = {yes} or {no} {label} arg = string string = character string (e.g. BONDS) to use in header of dump local file {nfile} arg = Nf Nf = write this many files, one from each of Nf processors {pad} arg = Nchar = # of characters to convert timestep to {pbc} arg = {yes} or {no} = remap atoms via periodic boundary conditions {precision} arg = power-of-10 value from 10 to 1000000 {region} arg = region-ID or "none" {scale} arg = {yes} or {no} {sfactor} arg = coordinate scaling factor (> 0.0) {tfactor} arg = time scaling factor (> 0.0) {sort} arg = {off} or {id} or N or -N off = no sorting of per-atom lines within a snapshot id = sort per-atom lines by atom ID N = sort per-atom lines in ascending order by the Nth column -N = sort per-atom lines in descending order by the Nth column {thresh} args = attribute operation value attribute = same attributes (x,fy,etotal,sxx,etc) used by dump custom style operation = "<" or "<=" or ">" or ">=" or "==" or "!=" or "|^" value = numeric value to compare to, or LAST these 3 args can be replaced by the word "none" to turn off thresholding {unwrap} arg = {yes} or {no} :pre these keywords apply only to the {image} and {movie} "styles"_dump_image.html :l keyword = {acolor} or {adiam} or {amap} or {backcolor} or {bcolor} or {bdiam} or {boxcolor} or {color} or {bitrate} or {framerate} :l {acolor} args = type color type = atom type or range of types (see below) color = name of color or color1/color2/... {adiam} args = type diam type = atom type or range of types (see below) diam = diameter of atoms of that type (distance units) {amap} args = lo hi style delta N entry1 entry2 ... entryN lo = number or {min} = lower bound of range of color map hi = number or {max} = upper bound of range of color map style = 2 letters = "c" or "d" or "s" plus "a" or "f" "c" for continuous "d" for discrete "s" for sequential "a" for absolute "f" for fractional delta = binsize (only used for style "s", otherwise ignored) binsize = range is divided into bins of this width N = # of subsequent entries entry = value color (for continuous style) value = number or {min} or {max} = single value within range color = name of color used for that value entry = lo hi color (for discrete style) lo/hi = number or {min} or {max} = lower/upper bound of subset of range color = name of color used for that subset of values entry = color (for sequential style) color = name of color used for a bin of values {backcolor} arg = color color = name of color for background {bcolor} args = type color type = bond type or range of types (see below) color = name of color or color1/color2/... {bdiam} args = type diam type = bond type or range of types (see below) diam = diameter of bonds of that type (distance units) {boxcolor} arg = color color = name of color for simulation box lines and processor sub-domain lines {color} args = name R G B name = name of color R,G,B = red/green/blue numeric values from 0.0 to 1.0 {bitrate} arg = rate rate = target bitrate for movie in kbps {framerate} arg = fps fps = frames per second for movie :pre :ule [Examples:] dump_modify 1 format line "%d %d %20.15g %g %g" scale yes dump_modify 1 format float %20.15g scale yes dump_modify myDump image yes scale no flush yes dump_modify 1 region mySphere thresh x < 0.0 thresh epair >= 3.2 dump_modify xtcdump precision 10000 sfactor 0.1 dump_modify 1 every 1000 nfile 20 dump_modify 1 every v_myVar dump_modify 1 amap min max cf 0.0 3 min green 0.5 yellow max blue boxcolor red :pre [Description:] Modify the parameters of a previously defined dump command. Not all parameters are relevant to all dump styles. As explained on the "dump"_dump.html doc page, the {atom/mpiio}, {custom/mpiio}, and {xyz/mpiio} dump styles are identical in command syntax and in the format of the dump files they create, to the corresponding styles without "mpiio", except the single dump file they produce is written in parallel via the MPI-IO library. Thus if a dump_modify option below is valid for the {atom} style, it is also valid for the {atom/mpiio} style, and similarly for the other styles which allow for use of MPI-IO. :line :line These keywords apply to various dump styles, including the "dump image"_dump_image.html and "dump movie"_dump_image.html styles. The description gives details. :line The {append} keyword applies to all dump styles except {cfg} and {xtc} and {dcd}. It also applies only to text output files, not to binary or gzipped or image/movie files. If specified as {yes}, then dump snapshots are appended to the end of an existing dump file. If specified as {no}, then a new dump file will be created which will overwrite an existing file with the same name. This keyword can only take effect if the dump_modify command is used after the "dump"_dump.html command, but before the first command that causes dump snapshots to be output, e.g. a "run"_run.html or "minimize"_minimize.html command. Once the dump file has been opened, this keyword has no further effect. :line The {buffer} keyword applies only to dump styles {atom}, {cfg}, {custom}, {local}, and {xyz}. It also applies only to text output files, not to binary or gzipped files. If specified as {yes}, which is the default, then each processor writes its output into an internal text buffer, which is then sent to the processor(s) which perform file writes, and written by those processors(s) as one large chunk of text. If specified as {no}, each processor sends its per-atom data in binary format to the processor(s) which perform file wirtes, and those processor(s) format and write it line by line into the output file. The buffering mode is typically faster since each processor does the relatively expensive task of formatting the output for its own atoms. However it requires about twice the memory (per processor) for the extra buffering. :line The {element} keyword applies only to the the dump {cfg}, {xyz}, and {image} styles. It associates element names (e.g. H, C, Fe) with LAMMPS atom types. See the list of element names at the bottom of this page. In the case of dump {cfg}, this allows the "AtomEye"_atomeye visualization package to read the dump file and render atoms with the appropriate size and color. In the case of dump {image}, the output images will follow the same "AtomEye"_atomeye convention. An element name is specified for each atom type (1 to Ntype) in the simulation. The same element name can be given to multiple atom types. In the case of {xyz} format dumps, there are no restrictions to what label can be used as an element name. Any whitespace separated text will be accepted. :link(atomeye,http://mt.seas.upenn.edu/Archive/Graphics/A) :line The {every} keyword changes the dump frequency originally specified by the "dump"_dump.html command to a new value. The every keyword can be specified in one of two ways. It can be a numeric value in which case it must be > 0. Or it can be an "equal-style variable"_variable.html, which should be specified as v_name, where name is the variable name. In this case, the variable is evaluated at the beginning of a run to determine the next timestep at which a dump snapshot will be written out. On that timestep the variable will be evaluated again to determine the next timestep, etc. Thus the variable should return timestep values. See the stagger() and logfreq() and stride() math functions for "equal-style variables"_variable.html, as examples of useful functions to use in this context. Other similar math functions could easily be added as options for "equal-style variables"_variable.html. Also see the next() function, which allows use of a file-style variable which reads successive values from a file, each time the variable is evaluated. Used with the {every} keyword, if the file contains a list of ascending timesteps, you can output snapshots whenever you wish. Note that when using the variable option with the {every} keyword, you need to use the {first} option if you want an initial snapshot written to the dump file. The {every} keyword cannot be used with the dump {dcd} style. For example, the following commands will write snapshots at timesteps 0,10,20,30,100,200,300,1000,2000,etc: -variable s equal logfreq(10,3,10) -dump 1 all atom 100 tmp.dump -dump_modify 1 every v_s first yes :pre +variable s equal logfreq(10,3,10) +dump 1 all atom 100 tmp.dump +dump_modify 1 every v_s first yes :pre The following commands would write snapshots at the timesteps listed in file tmp.times: variable f file tmp.times -variable s equal next(f) -dump 1 all atom 100 tmp.dump -dump_modify 1 every v_s :pre +variable s equal next(f) +dump 1 all atom 100 tmp.dump +dump_modify 1 every v_s :pre NOTE: When using a file-style variable with the {every} keyword, the file of timesteps must list a first timestep that is beyond the current timestep (e.g. it cannot be 0). And it must list one or more timesteps beyond the length of the run you perform. This is because the dump command will generate an error if the next timestep it reads from the file is not a value greater than the current timestep. Thus if you wanted output on steps 0,15,100 of a 100-timestep run, the file should contain the values 15,100,101 and you should also use the dump_modify first command. Any final value > 100 could be used in place of 101. :line The {first} keyword determines whether a dump snapshot is written on the very first timestep after the dump command is invoked. This will always occur if the current timestep is a multiple of N, the frequency specified in the "dump"_dump.html command, including timestep 0. But if this is not the case, a dump snapshot will only be written if the setting of this keyword is {yes}. If it is {no}, which is the default, then it will not be written. :line The {flush} keyword determines whether a flush operation is invoked after a dump snapshot is written to the dump file. A flush insures the output in that file is current (no buffering by the OS), even if LAMMPS halts before the simulation completes. Flushes cannot be performed with dump style {xtc}. :line The {format} keyword can be used to change the default numeric format output by the text-based dump styles: {atom}, {custom}, {cfg}, and {xyz} styles, and their MPIIO variants. Only the {line} or {none} options can be used with the {atom} and {xyz} styles. All the specified format strings are C-style formats, e.g. as used by the C/C++ printf() command. The {line} keyword takes a single argument which is the format string for an entire line of output for each atom (do not include a trailing "\n"), with N fields, which you must enclose in quotes if it is more than one field. The {int} and {float} keywords take a single format argument and are applied to all integer or floating-point quantities output. The setting for {M string} also takes a single format argument which is used for the Mth value output in each line, e.g. the 5th column is output in high precision for "format 5 %20.15g". NOTE: When using the {line} keyword for the {cfg} style, the first two fields (atom ID and type) are not actually written into the CFG file, however you must include formats for them in the format string. The {format} keyword can be used multiple times. The precedence is that for each value in a line of output, the {M} format (if specified) is used, else the {int} or {float} setting (if specified) is used, else the {line} setting (if specified) for that value is used, else the default setting is used. A setting of {none} clears all previous settings, reverting all values to their default format. NOTE: Atom and molecule IDs are stored internally as 4-byte or 8-byte signed integers, depending on how LAMMPS was compiled. When specifying the {format int} option you can use a "%d"-style format identifier in the format string and LAMMPS will convert this to the corresponding 8-byte form it it is needed when outputting those values. However, when specifying the {line} option or {format M string} option for those values, you should specify a format string appropriate for an 8-byte signed integer, e.g. one with "%ld", if LAMMPS was compiled with the -DLAMMPS_BIGBIG option for 8-byte IDs. NOTE: Any value written to a text-based dump file that is a per-atom quantity calculated by a "compute"_compute.html or "fix"_fix.html is stored internally as a floating-point value. If the value is actually an integer and you wish it to appear in the text dump file as a (large) integer, then you need to use an appropriate format. For example, these commands: compute 1 all property/local batom1 batom2 dump 1 all local 100 tmp.bonds index c_1\[1\] c_1\[2\] dump_modify 1 format "%d %0.0f %0.0f" :pre will output the two atom IDs for atoms in each bond as integers. If the dump_modify command were omitted, they would appear as floating-point values, assuming they were large integers (more than 6 digits). The "index" keyword should use the "%d" format since it is not generated by a compute or fix, and is stored internally as an integer. :line The {fileper} keyword is documented below with the {nfile} keyword. :line The {image} keyword applies only to the dump {atom} style. If the image value is {yes}, 3 flags are appended to each atom's coords which are the absolute box image of the atom in each dimension. For example, an x image flag of -2 with a normalized coord of 0.5 means the atom is in the center of the box, but has passed thru the box boundary 2 times and is really 2 box lengths to the left of its current coordinate. Note that for dump style {custom} these various values can be printed in the dump file by using the appropriate atom attributes in the dump command itself. :line The {label} keyword applies only to the dump {local} style. When it writes local information, such as bond or angle topology to a dump file, it will use the specified {label} to format the header. By default this includes 2 lines: ITEM: NUMBER OF ENTRIES ITEM: ENTRIES ... :pre The word "ENTRIES" will be replaced with the string specified, e.g. BONDS or ANGLES. :line The {nfile} or {fileper} keywords can be used in conjunction with the "%" wildcard character in the specified dump file name, for all dump styles except the {dcd}, {image}, {movie}, {xtc}, and {xyz} styles (for which "%" is not allowed). As explained on the "dump"_dump.html command doc page, the "%" character causes the dump file to be written in pieces, one piece for each of P processors. By default P = the number of processors the simulation is running on. The {nfile} or {fileper} keyword can be used to set P to a smaller value, which can be more efficient when running on a large number of processors. The {nfile} keyword sets P to the specified Nf value. For example, if Nf = 4, and the simulation is running on 100 processors, 4 files will be written, by processors 0,25,50,75. Each will collect information from itself and the next 24 processors and write it to a dump file. For the {fileper} keyword, the specified value of Np means write one file for every Np processors. For example, if Np = 4, every 4th processor (0,4,8,12,etc) will collect information from itself and the next 3 processors and write it to a dump file. :line The {pad} keyword only applies when the dump filename is specified with a wildcard "*" character which becomes the timestep. If {pad} is 0, which is the default, the timestep is converted into a string of unpadded length, e.g. 100 or 12000 or 2000000. When {pad} is specified with {Nchar} > 0, the string is padded with leading zeroes so they are all the same length = {Nchar}. For example, pad 7 would yield 0000100, 0012000, 2000000. This can be useful so that post-processing programs can easily read the files in ascending timestep order. :line The {pbc} keyword applies to all the dump styles. As explained on the "dump"_dump.html doc page, atom coordinates in a dump file may be slightly outside the simulation box. This is because periodic boundary conditions are enforced only on timesteps when neighbor lists are rebuilt, which will not typically coincide with the timesteps dump snapshots are written. If the setting of this keyword is set to {yes}, then all atoms will be remapped to the periodic box before the snapshot is written, then restored to their original position. If it is set to {no} they will not be. The {no} setting is the default because it requires no extra computation. :line The {precision} keyword only applies to the dump {xtc} style. A specified value of N means that coordinates are stored to 1/N nanometer accuracy, e.g. for N = 1000, the coordinates are written to 1/1000 nanometer accuracy. :line The {sfactor} and {tfactor} keywords only apply to the dump {xtc} style. They allow customization of the unit conversion factors used when writing to XTC files. By default they are initialized for whatever "units"_units.html style is being used, to write out coordinates in nanometers and time in picoseconds. I.e. for {real} units, LAMMPS defines {sfactor} = 0.1 and {tfactor} = 0.001, since the Angstroms and fmsec used by {real} units are 0.1 nm and 0.001 psec respectively. If you are using a units system with distance and time units far from nm and psec, you may wish to write XTC files with different units, since the compression algorithm used in XTC files is most effective when the typical magnitude of position data is between 10.0 and 0.1. :line The {region} keyword only applies to the dump {custom}, {cfg}, {image}, and {movie} styles. If specified, only atoms in the region will be written to the dump file or included in the image/movie. Only one region can be applied as a filter (the last one specified). See the "region"_region.html command for more details. Note that a region can be defined as the "inside" or "outside" of a geometric shape, and it can be the "union" or "intersection" of a series of simpler regions. :line The {scale} keyword applies only to the dump {atom} style. A scale value of {yes} means atom coords are written in normalized units from 0.0 to 1.0 in each box dimension. If the simluation box is triclinic (tilted), then all atom coords will still be between 0.0 and 1.0. A value of {no} means they are written in absolute distance units (e.g. Angstroms or sigma). :line The {sort} keyword determines whether lines of per-atom output in a snapshot are sorted or not. A sort value of {off} means they will typically be written in indeterminate order, either in serial or parallel. This is the case even in serial if the "atom_modify sort"_atom_modify.html option is turned on, which it is by default, to improve performance. A sort value of {id} means sort the output by atom ID. A sort value of N or -N means sort the output by the value in the Nth column of per-atom info in either ascending or descending order. The dump {local} style cannot be sorted by atom ID, since there are typically multiple lines of output per atom. Some dump styles, such as {dcd} and {xtc}, require sorting by atom ID to format the output file correctly. If multiple processors are writing the dump file, via the "%" wildcard in the dump filename, then sorting cannot be performed. NOTE: Unless it is required by the dump style, sorting dump file output requires extra overhead in terms of CPU and communication cost, as well as memory, versus unsorted output. :line The {thresh} keyword only applies to the dump {custom}, {cfg}, {image}, and {movie} styles. Multiple thresholds can be specified. Specifying {none} turns off all threshold criteria. If thresholds are specified, only atoms whose attributes meet all the threshold criteria are written to the dump file or included in the image. The possible attributes that can be tested for are the same as those that can be specified in the "dump custom"_dump.html command, with the exception of the {element} attribute, since it is not a numeric value. Note that a different attributes can be used than those output by the "dump custom"_dump.html command. E.g. you can output the coordinates and stress of atoms whose energy is above some threshold. If an atom-style variable is used as the attribute, then it can produce continuous numeric values or effective Boolean 0/1 values which may be useful for the comparision operation. Boolean values can be generated by variable formulas that use comparison or Boolean math operators or special functions like gmask() and rmask() and grmask(). See the "variable"_variable.html command doc page for details. NOTE: The LAST option, discussed below, is not yet implemented. It will be soon. The specified value must be a simple numeric value or the word LAST. If LAST is used, it refers to the value of the attribute the last time the dump command was invoked to produce a snapshot. This is a way to only dump atoms whose attribute has changed (or not changed). Three examples follow. dump_modify ... thresh ix != LAST :pre This will dump atoms which have crossed the periodic x boundary of the simulation box since the last dump. (Note that atoms that crossed once and then crossed back between the two dump timesteps would not be included.) region foo sphere 10 20 10 15 variable inregion atom rmask(foo) dump_modify ... thresh v_inregion |^ LAST This will dump atoms which crossed the boundary of the spherical region since the last dump. variable charge atom "(q > 0.5) || (q < -0.5)" dump_modify ... thresh v_charge |^ LAST This will dump atoms whose charge has changed from an absolute value less than 1/2 to greater than 1/2 (or vice versa) since the last dump. E.g. due to reactions and subsequent charge equilibration in a reactive force field. The choice of operations are the usual comparison operators. The XOR operation (exclusive or) is also included as "|^". In this context, XOR means that if either the attribute or value is 0.0 and the other is non-zero, then the result is "true" and the threshold criterion is met. Otherwise it is not met. :line The {unwrap} keyword only applies to the dump {dcd} and {xtc} styles. If set to {yes}, coordinates will be written "unwrapped" by the image flags for each atom. Unwrapped means that if the atom has passed thru a periodic boundary one or more times, the value is printed for what the coordinate would be if it had not been wrapped back into the periodic box. Note that these coordinates may thus be far outside the box size stored with the snapshot. :line :line These keywords apply only to the "dump image"_dump_image.html and "dump movie"_dump_image.html styles. Any keyword that affects an image, also affects a movie, since the movie is simply a collection of images. Some of the keywords only affect the "dump movie"_dump_image.html style. The descriptions give details. :line The {acolor} keyword can be used with the "dump image"_dump_image.html command, when its atom color setting is {type}, to set the color that atoms of each type will be drawn in the image. The specified {type} should be an integer from 1 to Ntypes = the number of atom types. A wildcard asterisk can be used in place of or in conjunction with the {type} argument to specify a range of atom types. This takes the form "*" or "*n" or "n*" or "m*n". If N = the number of atom types, then an asterisk with no numeric values means all types from 1 to N. A leading asterisk means all types from 1 to n (inclusive). A trailing asterisk means all types from n to N (inclusive). A middle asterisk means all types from m to n (inclusive). The specified {color} can be a single color which is any of the 140 pre-defined colors (see below) or a color name defined by the dump_modify color option. Or it can be two or more colors separated by a "/" character, e.g. red/green/blue. In the former case, that color is assigned to all the specified atom types. In the latter case, the list of colors are assigned in a round-robin fashion to each of the specified atom types. :line The {adiam} keyword can be used with the "dump image"_dump_image.html command, when its atom diameter setting is {type}, to set the size that atoms of each type will be drawn in the image. The specified {type} should be an integer from 1 to Ntypes. As with the {acolor} keyword, a wildcard asterisk can be used as part of the {type} argument to specify a range of atomt types. The specified {diam} is the size in whatever distance "units"_units.html the input script is using, e.g. Angstroms. :line The {amap} keyword can be used with the "dump image"_dump_image.html command, with its {atom} keyword, when its atom setting is an atom-attribute, to setup a color map. The color map is used to assign a specific RGB (red/green/blue) color value to an individual atom when it is drawn, based on the atom's attribute, which is a numeric value, e.g. its x-component of velocity if the atom-attribute "vx" was specified. The basic idea of a color map is that the atom-attribute will be within a range of values, and that range is associated with a a series of colors (e.g. red, blue, green). An atom's specific value (vx = -3.2) can then mapped to the series of colors (e.g. halfway between red and blue), and a specific color is determined via an interpolation procedure. There are many possible options for the color map, enabled by the {amap} keyword. Here are the details. The {lo} and {hi} settings determine the range of values allowed for the atom attribute. If numeric values are used for {lo} and/or {hi}, then values that are lower/higher than that value are set to the value. I.e. the range is static. If {lo} is specified as {min} or {hi} as {max} then the range is dynamic, and the lower and/or upper bound will be calculated each time an image is drawn, based on the set of atoms being visualized. The {style} setting is two letters, such as "ca". The first letter is either "c" for continuous, "d" for discrete, or "s" for sequential. The second letter is either "a" for absolute, or "f" for fractional. A continuous color map is one in which the color changes continuously from value to value within the range. A discrete color map is one in which discrete colors are assigned to sub-ranges of values within the range. A sequential color map is one in which discrete colors are assigned to a sequence of sub-ranges of values covering the entire range. An absolute color map is one in which the values to which colors are assigned are specified explicitly as values within the range. A fractional color map is one in which the values to which colors are assigned are specified as a fractional portion of the range. For example if the range is from -10.0 to 10.0, and the color red is to be assigned to atoms with a value of 5.0, then for an absolute color map the number 5.0 would be used. But for a fractional map, the number 0.75 would be used since 5.0 is 3/4 of the way from -10.0 to 10.0. The {delta} setting must be specified for all styles, but is only used for the sequential style; otherwise the value is ignored. It specifies the bin size to use within the range for assigning consecutive colors to. For example, if the range is from -10.0 to 10.0 and a {delta} of 1.0 is used, then 20 colors will be assigned to the range. The first will be from -10.0 <= color1 < -9.0, then 2nd from -9.0 <= color2 < -8.0, etc. The {N} setting is how many entries follow. The format of the entries depends on whether the color map style is continuous, discrete or sequential. In all cases the {color} setting can be any of the 140 pre-defined colors (see below) or a color name defined by the dump_modify color option. For continuous color maps, each entry has a {value} and a {color}. The {value} is either a number within the range of values or {min} or {max}. The {value} of the first entry must be {min} and the {value} of the last entry must be {max}. Any entries in between must have increasing values. Note that numeric values can be specified either as absolute numbers or as fractions (0.0 to 1.0) of the range, depending on the "a" or "f" in the style setting for the color map. Here is how the entries are used to determine the color of an individual atom, given the value X of its atom attribute. X will fall between 2 of the entry values. The color of the atom is linearly interpolated (in each of the RGB values) between the 2 colors associated with those entries. For example, if X = -5.0 and the 2 surrounding entries are "red" at -10.0 and "blue" at 0.0, then the atom's color will be halfway between "red" and "blue", which happens to be "purple". For discrete color maps, each entry has a {lo} and {hi} value and a {color}. The {lo} and {hi} settings are either numbers within the range of values or {lo} can be {min} or {hi} can be {max}. The {lo} and {hi} settings of the last entry must be {min} and {max}. Other entries can have any {lo} and {hi} values and the sub-ranges of different values can overlap. Note that numeric {lo} and {hi} values can be specified either as absolute numbers or as fractions (0.0 to 1.0) of the range, depending on the "a" or "f" in the style setting for the color map. Here is how the entries are used to determine the color of an individual atom, given the value X of its atom attribute. The entries are scanned from first to last. The first time that {lo} <= X <= {hi}, X is assigned the color associated with that entry. You can think of the last entry as assigning a default color (since it will always be matched by X), and the earlier entries as colors that override the default. Also note that no interpolation of a color RGB is done. All atoms will be drawn with one of the colors in the list of entries. For sequential color maps, each entry has only a {color}. Here is how the entries are used to determine the color of an individual atom, given the value X of its atom attribute. The range is partitioned into N bins of width {binsize}. Thus X will fall in a specific bin from 1 to N, say the Mth bin. If it falls on a boundary between 2 bins, it is considered to be in the higher of the 2 bins. Each bin is assigned a color from the E entries. If E < N, then the colors are repeated. For example if 2 entries with colors red and green are specified, then the odd numbered bins will be red and the even bins green. The color of the atom is the color of its bin. Note that the sequential color map is really a shorthand way of defining a discrete color map without having to specify where all the bin boundaries are. Here is an example of using a sequential color map to color all the atoms in individual molecules with a different color. See the examples/pour/in.pour.2d.molecule input script for an example of how this is used. variable colors string & "red green blue yellow white & purple pink orange lime gray" -variable mol atom mol%10 -dump 1 all image 250 image.*.jpg v_mol type & - zoom 1.6 adiam 1.5 -dump_modify 1 pad 5 amap 0 10 sa 1 10 $\{colors\} :pre +variable mol atom mol%10 +dump 1 all image 250 image.*.jpg v_mol type & + zoom 1.6 adiam 1.5 +dump_modify 1 pad 5 amap 0 10 sa 1 10 $\{colors\} :pre In this case, 10 colors are defined, and molecule IDs are mapped to one of the colors, even if there are 1000s of molecules. :line The {backcolor} sets the background color of the images. The color name can be any of the 140 pre-defined colors (see below) or a color name defined by the dump_modify color option. :line The {bcolor} keyword can be used with the "dump image"_dump_image.html command, with its {bond} keyword, when its color setting is {type}, to set the color that bonds of each type will be drawn in the image. The specified {type} should be an integer from 1 to Nbondtypes = the number of bond types. A wildcard asterisk can be used in place of or in conjunction with the {type} argument to specify a range of bond types. This takes the form "*" or "*n" or "n*" or "m*n". If N = the number of bond types, then an asterisk with no numeric values means all types from 1 to N. A leading asterisk means all types from 1 to n (inclusive). A trailing asterisk means all types from n to N (inclusive). A middle asterisk means all types from m to n (inclusive). The specified {color} can be a single color which is any of the 140 pre-defined colors (see below) or a color name defined by the dump_modify color option. Or it can be two or more colors separated by a "/" character, e.g. red/green/blue. In the former case, that color is assigned to all the specified bond types. In the latter case, the list of colors are assigned in a round-robin fashion to each of the specified bond types. :line The {bdiam} keyword can be used with the "dump image"_dump_image.html command, with its {bond} keyword, when its diam setting is {type}, to set the diameter that bonds of each type will be drawn in the image. The specified {type} should be an integer from 1 to Nbondtypes. As with the {bcolor} keyword, a wildcard asterisk can be used as part of the {type} argument to specify a range of bond types. The specified {diam} is the size in whatever distance "units"_units.html you are using, e.g. Angstroms. :line The {bitrate} keyword can be used with the "dump movie"_dump_image.html command to define the size of the resulting movie file and its quality via setting how many kbits per second are to be used for the movie file. Higher bitrates require less compression and will result in higher quality movies. The quality is also determined by the compression format and encoder. The default setting is 2000 kbit/s, which will result in average quality with older compression formats. NOTE: Not all movie file formats supported by dump movie allow the bitrate to be set. If not, the setting is silently ignored. :line The {boxcolor} keyword sets the color of the simulation box drawn around the atoms in each image as well as the color of processor sub-domain boundaries. See the "dump image box" command for how to specify that a box be drawn via the {box} keyword, and the sub-domain boundaries via the {subbox} keyword. The color name can be any of the 140 pre-defined colors (see below) or a color name defined by the dump_modify color option. :line The {color} keyword allows definition of a new color name, in addition to the 140-predefined colors (see below), and associates 3 red/green/blue RGB values with that color name. The color name can then be used with any other dump_modify keyword that takes a color name as a value. The RGB values should each be floating point values between 0.0 and 1.0 inclusive. When a color name is converted to RGB values, the user-defined color names are searched first, then the 140 pre-defined color names. This means you can also use the {color} keyword to overwrite one of the pre-defined color names with new RBG values. :line The {framerate} keyword can be used with the "dump movie"_dump_image.html command to define the duration of the resulting movie file. Movie files written by the dump {movie} command have a default frame rate of 24 frames per second and the images generated will be converted at that rate. Thus a sequence of 1000 dump images will result in a movie of about 42 seconds. To make a movie run longer you can either generate images more frequently or lower the frame rate. To speed a movie up, you can do the inverse. Using a frame rate higher than 24 is not recommended, as it will result in simply dropping the rendered images. It is more efficient to dump images less frequently. :line :line [Restrictions:] none [Related commands:] "dump"_dump.html, "dump image"_dump_image.html, "undump"_undump.html [Default:] The option defaults are append = no buffer = yes for dump styles {atom}, {custom}, {loca}, and {xyz} element = "C" for every atom type every = whatever it was set to via the "dump"_dump.html command fileper = # of processors first = no flush = yes format = %d and %g for each integer or floating point value image = no label = ENTRIES nfile = 1 pad = 0 pbc = no precision = 1000 region = none scale = yes sort = off for dump styles {atom}, {custom}, {cfg}, and {local} sort = id for dump styles {dcd}, {xtc}, and {xyz} thresh = none unwrap = no :ul acolor = * red/green/blue/yellow/aqua/cyan adiam = * 1.0 amap = min max cf 0.0 2 min blue max red backcolor = black bcolor = * red/green/blue/yellow/aqua/cyan bdiam = * 0.5 bitrate = 2000 boxcolor = yellow color = 140 color names are pre-defined as listed below framerate = 24 :ul :line These are the standard 109 element names that LAMMPS pre-defines for use with the "dump image"_dump_image.html and dump_modify commands. 1-10 = "H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne" 11-20 = "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca" 21-30 = "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn" 31-40 = "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr" 41-50 = "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn" 51-60 = "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd" 61-70 = "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb" 71-80 = "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg" 81-90 = "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac", "Th" 91-100 = "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm" 101-109 = "Md", "No", "Lr", "Rf", "Db", "Sg", "Bh", "Hs", "Mt" :ul :line These are the 140 colors that LAMMPS pre-defines for use with the "dump image"_dump_image.html and dump_modify commands. Additional colors can be defined with the dump_modify color command. The 3 numbers listed for each name are the RGB (red/green/blue) values. Divide each value by 255 to get the equivalent 0.0 to 1.0 value. aliceblue = 240, 248, 255 | antiquewhite = 250, 235, 215 | aqua = 0, 255, 255 | aquamarine = 127, 255, 212 | azure = 240, 255, 255 | beige = 245, 245, 220 | bisque = 255, 228, 196 | black = 0, 0, 0 | blanchedalmond = 255, 255, 205 | blue = 0, 0, 255 | blueviolet = 138, 43, 226 | brown = 165, 42, 42 | burlywood = 222, 184, 135 | cadetblue = 95, 158, 160 | chartreuse = 127, 255, 0 | chocolate = 210, 105, 30 | coral = 255, 127, 80 | cornflowerblue = 100, 149, 237 | cornsilk = 255, 248, 220 | crimson = 220, 20, 60 | cyan = 0, 255, 255 | darkblue = 0, 0, 139 | darkcyan = 0, 139, 139 | darkgoldenrod = 184, 134, 11 | darkgray = 169, 169, 169 | darkgreen = 0, 100, 0 | darkkhaki = 189, 183, 107 | darkmagenta = 139, 0, 139 | darkolivegreen = 85, 107, 47 | darkorange = 255, 140, 0 | darkorchid = 153, 50, 204 | darkred = 139, 0, 0 | darksalmon = 233, 150, 122 | darkseagreen = 143, 188, 143 | darkslateblue = 72, 61, 139 | darkslategray = 47, 79, 79 | darkturquoise = 0, 206, 209 | darkviolet = 148, 0, 211 | deeppink = 255, 20, 147 | deepskyblue = 0, 191, 255 | dimgray = 105, 105, 105 | dodgerblue = 30, 144, 255 | firebrick = 178, 34, 34 | floralwhite = 255, 250, 240 | forestgreen = 34, 139, 34 | fuchsia = 255, 0, 255 | gainsboro = 220, 220, 220 | ghostwhite = 248, 248, 255 | gold = 255, 215, 0 | goldenrod = 218, 165, 32 | gray = 128, 128, 128 | green = 0, 128, 0 | greenyellow = 173, 255, 47 | honeydew = 240, 255, 240 | hotpink = 255, 105, 180 | indianred = 205, 92, 92 | indigo = 75, 0, 130 | ivory = 255, 240, 240 | khaki = 240, 230, 140 | lavender = 230, 230, 250 | lavenderblush = 255, 240, 245 | lawngreen = 124, 252, 0 | lemonchiffon = 255, 250, 205 | lightblue = 173, 216, 230 | lightcoral = 240, 128, 128 | lightcyan = 224, 255, 255 | lightgoldenrodyellow = 250, 250, 210 | lightgreen = 144, 238, 144 | lightgrey = 211, 211, 211 | lightpink = 255, 182, 193 | lightsalmon = 255, 160, 122 | lightseagreen = 32, 178, 170 | lightskyblue = 135, 206, 250 | lightslategray = 119, 136, 153 | lightsteelblue = 176, 196, 222 | lightyellow = 255, 255, 224 | lime = 0, 255, 0 | limegreen = 50, 205, 50 | linen = 250, 240, 230 | magenta = 255, 0, 255 | maroon = 128, 0, 0 | mediumaquamarine = 102, 205, 170 | mediumblue = 0, 0, 205 | mediumorchid = 186, 85, 211 | mediumpurple = 147, 112, 219 | mediumseagreen = 60, 179, 113 | mediumslateblue = 123, 104, 238 | mediumspringgreen = 0, 250, 154 | mediumturquoise = 72, 209, 204 | mediumvioletred = 199, 21, 133 | midnightblue = 25, 25, 112 | mintcream = 245, 255, 250 | mistyrose = 255, 228, 225 | moccasin = 255, 228, 181 | navajowhite = 255, 222, 173 | navy = 0, 0, 128 | oldlace = 253, 245, 230 | olive = 128, 128, 0 | olivedrab = 107, 142, 35 | orange = 255, 165, 0 | orangered = 255, 69, 0 | orchid = 218, 112, 214 | palegoldenrod = 238, 232, 170 | palegreen = 152, 251, 152 | paleturquoise = 175, 238, 238 | palevioletred = 219, 112, 147 | papayawhip = 255, 239, 213 | peachpuff = 255, 239, 213 | peru = 205, 133, 63 | pink = 255, 192, 203 | plum = 221, 160, 221 | powderblue = 176, 224, 230 | purple = 128, 0, 128 | red = 255, 0, 0 | rosybrown = 188, 143, 143 | royalblue = 65, 105, 225 | saddlebrown = 139, 69, 19 | salmon = 250, 128, 114 | sandybrown = 244, 164, 96 | seagreen = 46, 139, 87 | seashell = 255, 245, 238 | sienna = 160, 82, 45 | silver = 192, 192, 192 | skyblue = 135, 206, 235 | slateblue = 106, 90, 205 | slategray = 112, 128, 144 | snow = 255, 250, 250 | springgreen = 0, 255, 127 | steelblue = 70, 130, 180 | tan = 210, 180, 140 | teal = 0, 128, 128 | thistle = 216, 191, 216 | tomato = 253, 99, 71 | turquoise = 64, 224, 208 | violet = 238, 130, 238 | wheat = 245, 222, 179 | white = 255, 255, 255 | whitesmoke = 245, 245, 245 | yellow = 255, 255, 0 | yellowgreen = 154, 205, 50 :tb(c=5,s=|) diff --git a/doc/src/fix_ave_correlate.txt b/doc/src/fix_ave_correlate.txt index 021c00b06..bd097f291 100644 --- a/doc/src/fix_ave_correlate.txt +++ b/doc/src/fix_ave_correlate.txt @@ -1,370 +1,370 @@ "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 fix ave/correlate command :h3 [Syntax:] fix ID group-ID ave/correlate Nevery Nrepeat Nfreq value1 value2 ... keyword args ... :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l ave/correlate = style name of this fix command :l Nevery = use input values every this many timesteps :l Nrepeat = # of correlation time windows to accumulate :l Nfreq = calculate time window averages every this many timesteps :l one or more input values can be listed :l value = c_ID, c_ID\[N\], f_ID, f_ID\[N\], v_name :l c_ID = global scalar calculated by a compute with ID c_ID\[I\] = Ith component of global vector calculated by a compute with ID, I can include wildcard (see below) f_ID = global scalar calculated by a fix with ID f_ID\[I\] = Ith component of global vector calculated by a fix with ID, I can include wildcard (see below) v_name = global value calculated by an equal-style variable with name v_name\[I\] = Ith component of a vector-style variable with name :pre zero or more keyword/arg pairs may be appended :l keyword = {type} or {ave} or {start} or {prefactor} or {file} or {overwrite} or {title1} or {title2} or {title3} :l {type} arg = {auto} or {upper} or {lower} or {auto/upper} or {auto/lower} or {full} auto = correlate each value with itself upper = correlate each value with each succeeding value lower = correlate each value with each preceding value auto/upper = auto + upper auto/lower = auto + lower full = correlate each value with every other value, including itself = auto + upper + lower {ave} args = {one} or {running} one = zero the correlation accumulation every Nfreq steps running = accumulate correlations continuously {start} args = Nstart Nstart = start accumulating correlations on this timestep {prefactor} args = value value = prefactor to scale all the correlation data by {file} arg = filename filename = name of file to output correlation data to {overwrite} arg = none = overwrite output file with only latest output {title1} arg = string string = text to print as 1st line of output file {title2} arg = string string = text to print as 2nd line of output file {title3} arg = string string = text to print as 3rd line of output file :pre :ule [Examples:] fix 1 all ave/correlate 5 100 1000 c_myTemp file temp.correlate fix 1 all ave/correlate 1 50 10000 & c_thermo_press\[1\] c_thermo_press\[2\] c_thermo_press\[3\] & - type upper ave running title1 "My correlation data" :pre + type upper ave running title1 "My correlation data" :pre fix 1 all ave/correlate 1 50 10000 c_thermo_press\[*\] [Description:] Use one or more global scalar values as inputs every few timesteps, calculate time correlations bewteen them at varying time intervals, and average the correlation data over longer timescales. The resulting correlation values can be time integrated by "variables"_variable.html or used by other "output commands"_Section_howto.html#howto_15 such as "thermo_style custom"_thermo_style.html, and can also be written to a file. See the "fix ave/correlate/long"_fix_ave_correlate_long.html command for an alternate method for computing correlation functions efficiently over very long time windows. The group specified with this command is ignored. However, note that specified values may represent calculations performed by computes and fixes which store their own "group" definitions. Each listed value can be the result of a "compute"_compute.html or "fix"_fix.html or the evaluation of an equal-style or vector-style "variable"_variable.html. In each case, the compute, fix, or variable must produce a global quantity, not a per-atom or local quantity. If you wish to spatial- or time-average or histogram per-atom quantities from a compute, fix, or variable, then see the "fix ave/chunk"_fix_ave_chunk.html, "fix ave/atom"_fix_ave_atom.html, or "fix ave/histo"_fix_ave_histo.html commands. If you wish to convert a per-atom quantity into a single global value, see the "compute reduce"_compute_reduce.html command. The input values must either be all scalars. What kinds of correlations between input values are calculated is determined by the {type} keyword as discussed below. "Computes"_compute.html that produce global quantities are those which do not have the word {atom} in their style name. Only a few "fixes"_fix.html produce global quantities. See the doc pages for individual fixes for info on which ones produce such values. "Variables"_variable.html of style {equal} and {vector} are the only ones that can be used with this fix. Variables of style {atom} cannot be used, since they produce per-atom values. Note that for values from a compute or fix, the bracketed index I can be specified using a wildcard asterisk with the index to effectively specify multiple values. This takes the form "*" or "*n" or "n*" or "m*n". If N = the size of the vector (for {mode} = scalar) or the number of columns in the array (for {mode} = vector), then an asterisk with no numeric values means all indices from 1 to N. A leading asterisk means all indices from 1 to n (inclusive). A trailing asterisk means all indices from n to N (inclusive). A middle asterisk means all indices from m to n (inclusive). Using a wildcard is the same as if the individual elements of the vector had been listed one by one. E.g. these 2 fix ave/correlate commands are equivalent, since the "compute pressure"_compute_pressure.html command creates a global vector with 6 values. compute myPress all pressure NULL fix 1 all ave/correlate 1 50 10000 c_myPress\[*\] fix 1 all ave/correlate 1 50 10000 & c_myPress\[1\] c_myPress\[2\] c_myPress\[3\] & c_myPress\[4\] c_myPress\[5\] c_myPress\[6\] :pre :line The {Nevery}, {Nrepeat}, and {Nfreq} arguments specify on what timesteps the input values will be used to calculate correlation data. The input values are sampled every {Nevery} timesteps. The correlation data for the preceding samples is computed on timesteps that are a multiple of {Nfreq}. Consider a set of samples from some initial time up to an output timestep. The initial time could be the beginning of the simulation or the last output time; see the {ave} keyword for options. For the set of samples, the correlation value Cij is calculated as: Cij(delta) = ave(Vi(t)*Vj(t+delta)) :pre which is the correlation value between input values Vi and Vj, separated by time delta. Note that the second value Vj in the pair is always the one sampled at the later time. The ave() represents an average over every pair of samples in the set that are separated by time delta. The maximum delta used is of size ({Nrepeat}-1)*{Nevery}. Thus the correlation between a pair of input values yields {Nrepeat} correlation datums: Cij(0), Cij(Nevery), Cij(2*Nevery), ..., Cij((Nrepeat-1)*Nevery) :pre For example, if Nevery=5, Nrepeat=6, and Nfreq=100, then values on timesteps 0,5,10,15,...,100 will be used to compute the final averages on timestep 100. Six averages will be computed: Cij(0), Cij(5), Cij(10), Cij(15), Cij(20), and Cij(25). Cij(10) on timestep 100 will be the average of 19 samples, namely Vi(0)*Vj(10), Vi(5)*Vj(15), Vi(10)*V j20), Vi(15)*Vj(25), ..., Vi(85)*Vj(95), Vi(90)*Vj(100). {Nfreq} must be a multiple of {Nevery}; {Nevery} and {Nrepeat} must be non-zero. Also, if the {ave} keyword is set to {one} which is the default, then {Nfreq} >= ({Nrepeat}-1)*{Nevery} is required. :line If a value begins with "c_", a compute ID must follow which has been previously defined in the input script. If no bracketed term is appended, the global scalar calculated by the compute is used. If a bracketed term is appended, the Ith element of the global vector calculated by the compute is used. See the discussion above for how I can be specified with a wildcard asterisk to effectively specify multiple values. Note that there is a "compute reduce"_compute_reduce.html command which can sum per-atom quantities into a global scalar or vector which can thus be accessed by fix ave/correlate. Or it can be a compute defined not in your input script, but by "thermodynamic output"_thermo_style.html or other fixes such as "fix nvt"_fix_nh.html or "fix temp/rescale"_fix_temp_rescale.html. See the doc pages for these commands which give the IDs of these computes. Users can also write code for their own compute styles and "add them to LAMMPS"_Section_modify.html. If a value begins with "f_", a fix ID must follow which has been previously defined in the input script. If no bracketed term is appended, the global scalar calculated by the fix is used. If a bracketed term is appended, the Ith element of the global vector calculated by the fix is used. See the discussion above for how I can be specified with a wildcard asterisk to effectively specify multiple values. Note that some fixes only produce their values on certain timesteps, which must be compatible with {Nevery}, else an error will result. Users can also write code for their own fix styles and "add them to LAMMPS"_Section_modify.html. If a value begins with "v_", a variable name must follow which has been previously defined in the input script. Only equal-style or vector-style variables can be referenced; the latter requires a bracketed term to specify the Ith element of the vector calculated by the variable. See the "variable"_variable.html command for details. Note that variables of style {equal} or {vector} define a formula which can reference individual atom properties or thermodynamic keywords, or they can invoke other computes, fixes, or variables when they are evaluated, so this is a very general means of specifying quantities to time correlate. :line Additional optional keywords also affect the operation of this fix. The {type} keyword determines which pairs of input values are correlated with each other. For N input values Vi, for i = 1 to N, let the number of pairs = Npair. Note that the second value in the pair Vi(t)*Vj(t+delta) is always the one sampled at the later time. If {type} is set to {auto} then each input value is correlated with itself. I.e. Cii = Vi*Vi, for i = 1 to N, so Npair = N. :ulb,l If {type} is set to {upper} then each input value is correlated with every succeeding value. I.e. Cij = Vi*Vj, for i < j, so Npair = N*(N-1)/2. :l If {type} is set to {lower} then each input value is correlated with every preceeding value. I.e. Cij = Vi*Vj, for i > j, so Npair = N*(N-1)/2. :l If {type} is set to {auto/upper} then each input value is correlated with itself and every succeeding value. I.e. Cij = Vi*Vj, for i >= j, so Npair = N*(N+1)/2. :l If {type} is set to {auto/lower} then each input value is correlated with itself and every preceding value. I.e. Cij = Vi*Vj, for i <= j, so Npair = N*(N+1)/2. :l If {type} is set to {full} then each input value is correlated with itself and every other value. I.e. Cij = Vi*Vj, for i,j = 1,N so Npair = N^2. :l :ule The {ave} keyword determines what happens to the accumulation of correlation samples every {Nfreq} timesteps. If the {ave} setting is {one}, then the accumulation is restarted or zeroed every {Nfreq} timesteps. Thus the outputs on successive {Nfreq} timesteps are essentially independent of each other. The exception is that the Cij(0) = Vi(T)*Vj(T) value at a timestep T, where T is a multiple of {Nfreq}, contributes to the correlation output both at time T and at time T+Nfreq. If the {ave} setting is {running}, then the accumulation is never zeroed. Thus the output of correlation data at any timestep is the average over samples accumulated every {Nevery} steps since the fix was defined. it can only be restarted by deleting the fix via the "unfix"_unfix.html command, or by re-defining the fix by re-specifying it. The {start} keyword specifies what timestep the accumulation of correlation samples will begin on. The default is step 0. Setting it to a larger value can avoid adding non-equilibrated data to the correlation averages. The {prefactor} keyword specifies a constant which will be used as a multiplier on the correlation data after it is averaged. It is effectively a scale factor on Vi*Vj, which can be used to account for the size of the time window or other unit conversions. The {file} keyword allows a filename to be specified. Every {Nfreq} steps, an array of correlation data is written to the file. The number of rows is {Nrepeat}, as described above. The number of columns is the Npair+2, also as described above. Thus the file ends up to be a series of these array sections. The {overwrite} keyword will continuously overwrite the output file with the latest output, so that it only contains one timestep worth of output. This option can only be used with the {ave running} setting. The {title1} and {title2} and {title3} keywords allow specification of the strings that will be printed as the first 3 lines of the output file, assuming the {file} keyword was used. LAMMPS uses default values for each of these, so they do not need to be specified. By default, these header lines are as follows: # Time-correlated data for fix ID # TimeStep Number-of-time-windows # Index TimeDelta Ncount valueI*valueJ valueI*valueJ ... :pre In the first line, ID is replaced with the fix-ID. The second line describes the two values that are printed at the first of each section of output. In the third line the value pairs are replaced with the appropriate fields from the fix ave/correlate command. :line Let Sij = a set of time correlation data for input values I and J, namely the {Nrepeat} values: Sij = Cij(0), Cij(Nevery), Cij(2*Nevery), ..., Cij(*Nrepeat-1)*Nevery) :pre As explained below, these datums are output as one column of a global array, which is effectively the correlation matrix. The {trap} function defined for "equal-style variables"_variable.html can be used to perform a time integration of this vector of datums, using a trapezoidal rule. This is useful for calculating various quantities which can be derived from time correlation data. If a normalization factor is needed for the time integration, it can be included in the variable formula or via the {prefactor} keyword. :line [Restart, fix_modify, output, run start/stop, minimize info:] No information about this fix is written to "binary restart files"_restart.html. None of the "fix_modify"_fix_modify.html options are relevant to this fix. This fix computes a global array of values which can be accessed by various "output commands"_Section_howto.html#howto_15. The values can only be accessed on timesteps that are multiples of {Nfreq} since that is when averaging is performed. The global array has # of rows = {Nrepeat} and # of columns = Npair+2. The first column has the time delta (in timesteps) between the pairs of input values used to calculate the correlation, as described above. The 2nd column has the number of samples contributing to the correlation average, as described above. The remaining Npair columns are for I,J pairs of the N input values, as determined by the {type} keyword, as described above. For {type} = {auto}, the Npair = N columns are ordered: C11, C22, ..., CNN. :ulb,l For {type} = {upper}, the Npair = N*(N-1)/2 columns are ordered: C12, C13, ..., C1N, C23, ..., C2N, C34, ..., CN-1N. :l For {type} = {lower}, the Npair = N*(N-1)/2 columns are ordered: C21, C31, C32, C41, C42, C43, ..., CN1, CN2, ..., CNN-1. :l For {type} = {auto/upper}, the Npair = N*(N+1)/2 columns are ordered: C11, C12, C13, ..., C1N, C22, C23, ..., C2N, C33, C34, ..., CN-1N, CNN. :l For {type} = {auto/lower}, the Npair = N*(N+1)/2 columns are ordered: C11, C21, C22, C31, C32, C33, C41, ..., C44, CN1, CN2, ..., CNN-1, CNN. :l For {type} = {full}, the Npair = N^2 columns are ordered: C11, C12, ..., C1N, C21, C22, ..., C2N, C31, ..., C3N, ..., CN1, ..., CNN-1, CNN. :l :ule The array values calculated by this fix are treated as intensive. If you need to divide them by the number of atoms, you must do this in a later processing step, e.g. when using them in a "variable"_variable.html. No parameter of this fix can be used with the {start/stop} keywords of the "run"_run.html command. This fix is not invoked during "energy minimization"_minimize.html. [Restrictions:] none [Related commands:] "fix ave/correlate/long"_fix_ave_correlate_long.html, "compute"_compute.html, "fix ave/time"_fix_ave_time.html, "fix ave/atom"_fix_ave_atom.html, "fix ave/chunk"_fix_ave_chunk.html, "fix ave/histo"_fix_ave_histo.html, "variable"_variable.html [Default:] none The option defaults are ave = one, type = auto, start = 0, no file output, title 1,2,3 = strings as described above, and prefactor = 1.0. diff --git a/doc/src/fix_ave_correlate_long.txt b/doc/src/fix_ave_correlate_long.txt index e744ad4cb..7b4bc5370 100644 --- a/doc/src/fix_ave_correlate_long.txt +++ b/doc/src/fix_ave_correlate_long.txt @@ -1,144 +1,144 @@ "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 fix ave/correlate/long command :h3 [Syntax:] fix ID group-ID ave/correlate/long Nevery Nfreq value1 value2 ... keyword args ... :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l ave/correlate/long = style name of this fix command :l Nevery = use input values every this many timesteps :l Nfreq = save state of the time correlation functions every this many timesteps :l one or more input values can be listed :l value = c_ID, c_ID\[N\], f_ID, f_ID\[N\], v_name :l c_ID = global scalar calculated by a compute with ID c_ID\[I\] = Ith component of global vector calculated by a compute with ID f_ID = global scalar calculated by a fix with ID f_ID\[I\] = Ith component of global vector calculated by a fix with ID v_name = global value calculated by an equal-style variable with name :pre zero or more keyword/arg pairs may be appended :l keyword = {type} or {start} or {file} or {overwrite} or {title1} or {title2} or {ncorr} or {p} or {m} :l {type} arg = {auto} or {upper} or {lower} or {auto/upper} or {auto/lower} or {full} auto = correlate each value with itself upper = correlate each value with each succeeding value lower = correlate each value with each preceding value auto/upper = auto + upper auto/lower = auto + lower full = correlate each value with every other value, including itself = auto + upper + lower {start} args = Nstart Nstart = start accumulating correlations on this timestep {file} arg = filename filename = name of file to output correlation data to {overwrite} arg = none = overwrite output file with only latest output {title1} arg = string string = text to print as 1st line of output file {title2} arg = string string = text to print as 2nd line of output file {ncorr} arg = Ncorrelators Ncorrelators = number of correlators to store {nlen} args = Nlen Nlen = length of each correlator {ncount} args = Ncount Ncount = number of values over which succesive correlators are averaged :pre :ule [Examples:] fix 1 all ave/correlate/long 5 1000 c_myTemp file temp.correlate fix 1 all ave/correlate/long 1 10000 & c_thermo_press\[1\] c_thermo_press\[2\] c_thermo_press\[3\] & - type upper title1 "My correlation data" nlen 15 ncount 3 :pre + type upper title1 "My correlation data" nlen 15 ncount 3 :pre [Description:] This fix is similar in spirit and syntax to the "fix ave/correlate"_fix_ave_correlate.html. However, this fix allows the efficient calculation of time correlation functions on the fly over extremely long time windows without too much CPU overhead, using a multiple-tau method "(Ramirez)"_#Ramirez that decreases the resolution of the stored correlation function with time. The group specified with this command is ignored. However, note that specified values may represent calculations performed by computes and fixes which store their own "group" definitions. Each listed value can be the result of a compute or fix or the evaluation of an equal-style variable. See the "fix ave/correlate"_fix_ave_correlate.html doc page for details. The {Nevery} and {Nfreq} arguments specify on what timesteps the input values will be used to calculate correlation data, and the frequency with which the time correlation functions will be output to a file. Note that there is no {Nrepeat} argument, unlike the "fix ave/correlate"_fix_ave_correlate.html command. The optional keywords {ncorr}, {nlen}, and {ncount} are unique to this command and determine the number of correlation points calculated and the memory and CPU overhead used by this calculation. {Nlen} and {ncount} determine the amount of averaging done at longer correlation times. The default values {nlen=16}, {ncount=2} ensure that the systematic error of the multiple-tau correlator is always below the level of the statistical error of a typical simulation (which depends on the ensemble size and the simulation length). The maximum correlation time (in time steps) that can be reached is given by the formula (nlen-1) * ncount^(ncorr-1). Longer correlation times are discarded and not calculated. With the default values of the parameters (ncorr=20, nlen=16 and ncount=2), this corresponds to 7864320 time steps. If longer correlation times are needed, the value of ncorr should be increased. Using nlen=16 and ncount=2, with ncorr=30, the maximum number of steps that can be correlated is 80530636808. If ncorr=40, correlation times in excess of 8e12 time steps can be calculated. The total memory needed for each correlation pair is roughly 4*ncorr*nlen*8 bytes. With the default values of the parameters, this corresponds to about 10 KB. For the meaning of the additional optional keywords, see the "fix ave/correlate"_fix_ave_correlate.html doc page. [Restart, fix_modify, output, run start/stop, minimize info:] Since this fix in intended for the calculation of time correlation functions over very long MD simulations, the information about this fix is written automatically to binary restart files, so that the time correlation calculation can continue in subsequent simulations. None of the fix_modify options are relevant to this fix. No parameter of this fix can be used with the start/stop keywords of the run command. This fix is not invoked during energy minimization. [Restrictions:] This compute is part of the USER-MISC 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. [Related commands:] "fix ave/correlate"_fix_ave_correlate.html [Default:] none The option defaults for keywords that are also keywords for the "fix ave/correlate"_fix_ave_correlate.html command are as follows: type = auto, start = 0, no file output, title 1,2 = strings as described on the "fix ave/correlate"_fix_ave_correlate.html doc page. The option defaults for keywords unique to this command are as follows: ncorr=20, nlen=16, ncount=2. :line :link(Ramirez) [(Ramirez)] J. Ramirez, S.K. Sukumaran, B. Vorselaars and A.E. Likhtman, J. Chem. Phys. 133, 154103 (2010). diff --git a/doc/src/fix_bond_break.txt b/doc/src/fix_bond_break.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_bond_create.txt b/doc/src/fix_bond_create.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_bond_swap.txt b/doc/src/fix_bond_swap.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_deform.txt b/doc/src/fix_deform.txt index 01884803a..ffda84bf1 100644 --- a/doc/src/fix_deform.txt +++ b/doc/src/fix_deform.txt @@ -1,594 +1,594 @@ "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 fix deform command :h3 fix deform/kk command :h3 [Syntax:] fix ID group-ID deform N parameter args ... keyword value ... :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l deform = style name of this fix command :l N = perform box deformation every this many timesteps :l one or more parameter/arg pairs may be appended :l parameter = {x} or {y} or {z} or {xy} or {xz} or {yz} {x}, {y}, {z} args = style value(s) style = {final} or {delta} or {scale} or {vel} or {erate} or {trate} or {volume} or {wiggle} or {variable} {final} values = lo hi lo hi = box boundaries at end of run (distance units) {delta} values = dlo dhi dlo dhi = change in box boundaries at end of run (distance units) {scale} values = factor factor = multiplicative factor for change in box length at end of run {vel} value = V V = change box length at this velocity (distance/time units), - effectively an engineering strain rate + effectively an engineering strain rate {erate} value = R R = engineering strain rate (1/time units) {trate} value = R R = true strain rate (1/time units) {volume} value = none = adjust this dim to preserve volume of system {wiggle} values = A Tp A = amplitude of oscillation (distance units) - Tp = period of oscillation (time units) + Tp = period of oscillation (time units) {variable} values = v_name1 v_name2 v_name1 = variable with name1 for box length change as function of time - v_name2 = variable with name2 for change rate as function of time + v_name2 = variable with name2 for change rate as function of time {xy}, {xz}, {yz} args = style value style = {final} or {delta} or {vel} or {erate} or {trate} or {wiggle} {final} value = tilt tilt = tilt factor at end of run (distance units) {delta} value = dtilt dtilt = change in tilt factor at end of run (distance units) {vel} value = V V = change tilt factor at this velocity (distance/time units), - effectively an engineering shear strain rate + effectively an engineering shear strain rate {erate} value = R R = engineering shear strain rate (1/time units) {trate} value = R R = true shear strain rate (1/time units) {wiggle} values = A Tp A = amplitude of oscillation (distance units) - Tp = period of oscillation (time units) + Tp = period of oscillation (time units) {variable} values = v_name1 v_name2 v_name1 = variable with name1 for tilt change as function of time - v_name2 = variable with name2 for change rate as function of time :pre + v_name2 = variable with name2 for change rate as function of time :pre zero or more keyword/value pairs may be appended :l keyword = {remap} or {flip} or {units} :l {remap} value = {x} or {v} or {none} x = remap coords of atoms in group into deforming box v = remap velocities of all atoms when they cross periodic boundaries none = no remapping of x or v {flip} value = {yes} or {no} allow or disallow box flips when it becomes highly skewed {units} value = {lattice} or {box} lattice = distances are defined in lattice units box = distances are defined in simulation box units :pre :ule [Examples:] fix 1 all deform 1 x final 0.0 9.0 z final 0.0 5.0 units box fix 1 all deform 1 x trate 0.1 y volume z volume fix 1 all deform 1 xy erate 0.001 remap v fix 1 all deform 10 y delta -0.5 0.5 xz vel 1.0 :pre [Description:] Change the volume and/or shape of the simulation box during a dynamics run. Orthogonal simulation boxes have 3 adjustable parameters (x,y,z). Triclinic (non-orthogonal) simulation boxes have 6 adjustable parameters (x,y,z,xy,xz,yz). Any or all of them can be adjusted independently and simultaneously by this command. This fix can be used to perform non-equilibrium MD (NEMD) simulations of a continuously strained system. See the "fix nvt/sllod"_fix_nvt_sllod.html and "compute temp/deform"_compute_temp_deform.html commands for more details. For the {x}, {y}, {z} parameters, the associated dimension cannot be shrink-wrapped. For the {xy}, {yz}, {xz} parameters, the associated 2nd dimension cannot be shrink-wrapped. Dimensions not varied by this command can be periodic or non-periodic. Dimensions corresponding to unspecified parameters can also be controlled by a "fix npt"_fix_nh.html or "fix nph"_fix_nh.html command. The size and shape of the simulation box at the beginning of the simulation run were either specified by the "create_box"_create_box.html or "read_data"_read_data.html or "read_restart"_read_restart.html command used to setup the simulation initially if it is the first run, or they are the values from the end of the previous run. The "create_box"_create_box.html, "read data"_read_data.html, and "read_restart"_read_restart.html commands specify whether the simulation box is orthogonal or non-orthogonal (triclinic) and explain the meaning of the xy,xz,yz tilt factors. If fix deform changes the xy,xz,yz tilt factors, then the simulation box must be triclinic, even if its initial tilt factors are 0.0. As described below, the desired simulation box size and shape at the end of the run are determined by the parameters of the fix deform command. Every Nth timestep during the run, the simulation box is expanded, contracted, or tilted to ramped values between the initial and final values. :line For the {x}, {y}, and {z} parameters, this is the meaning of their styles and values. The {final}, {delta}, {scale}, {vel}, and {erate} styles all change the specified dimension of the box via "constant displacement" which is effectively a "constant engineering strain rate". This means the box dimension changes linearly with time from its initial to final value. For style {final}, the final lo and hi box boundaries of a dimension are specified. The values can be in lattice or box distance units. See the discussion of the units keyword below. For style {delta}, plus or minus changes in the lo/hi box boundaries of a dimension are specified. The values can be in lattice or box distance units. See the discussion of the units keyword below. For style {scale}, a multiplicative factor to apply to the box length of a dimension is specified. For example, if the initial box length is 10, and the factor is 1.1, then the final box length will be 11. A factor less than 1.0 means compression. For style {vel}, a velocity at which the box length changes is specified in units of distance/time. This is effectively a "constant engineering strain rate", where rate = V/L0 and L0 is the initial box length. The distance can be in lattice or box distance units. See the discussion of the units keyword below. For example, if the initial box length is 100 Angstroms, and V is 10 Angstroms/psec, then after 10 psec, the box length will have doubled. After 20 psec, it will have tripled. The {erate} style changes a dimension of the the box at a "constant engineering strain rate". The units of the specified strain rate are 1/time. See the "units"_units.html command for the time units associated with different choices of simulation units, e.g. picoseconds for "metal" units). Tensile strain is unitless and is defined as delta/L0, where L0 is the original box length and delta is the change relative to the original length. The box length L as a function of time will change as L(t) = L0 (1 + erate*dt) :pre where dt is the elapsed time (in time units). Thus if {erate} R is specified as 0.1 and time units are picoseconds, this means the box length will increase by 10% of its original length every picosecond. I.e. strain after 1 psec = 0.1, strain after 2 psec = 0.2, etc. R = -0.01 means the box length will shrink by 1% of its original length every picosecond. Note that for an "engineering" rate the change is based on the original box length, so running with R = 1 for 10 picoseconds expands the box length by a factor of 11 (strain of 10), which is different that what the {trate} style would induce. The {trate} style changes a dimension of the box at a "constant true strain rate". Note that this is not an "engineering strain rate", as the other styles are. Rather, for a "true" rate, the rate of change is constant, which means the box dimension changes non-linearly with time from its initial to final value. The units of the specified strain rate are 1/time. See the "units"_units.html command for the time units associated with different choices of simulation units, e.g. picoseconds for "metal" units). Tensile strain is unitless and is defined as delta/L0, where L0 is the original box length and delta is the change relative to the original length. The box length L as a function of time will change as L(t) = L0 exp(trate*dt) :pre where dt is the elapsed time (in time units). Thus if {trate} R is specified as ln(1.1) and time units are picoseconds, this means the box length will increase by 10% of its current (not original) length every picosecond. I.e. strain after 1 psec = 0.1, strain after 2 psec = 0.21, etc. R = ln(2) or ln(3) means the box length will double or triple every picosecond. R = ln(0.99) means the box length will shrink by 1% of its current length every picosecond. Note that for a "true" rate the change is continuous and based on the current length, so running with R = ln(2) for 10 picoseconds does not expand the box length by a factor of 11 as it would with {erate}, but by a factor of 1024 since the box length will double every picosecond. Note that to change the volume (or cross-sectional area) of the simulation box at a constant rate, you can change multiple dimensions via {erate} or {trate}. E.g. to double the box volume in a picosecond picosecond, you could set "x erate M", "y erate M", "z erate M", with M = pow(2,1/3) - 1 = 0.26, since if each box dimension grows by 26%, the box volume doubles. Or you could set "x trate M", "y trate M", "z trate M", with M = ln(1.26) = 0.231, and the box volume would double every picosecond. The {volume} style changes the specified dimension in such a way that the box volume remains constant while other box dimensions are changed explicitly via the styles discussed above. For example, "x scale 1.1 y scale 1.1 z volume" will shrink the z box length as the x,y box lengths increase, to keep the volume constant (product of x,y,z lengths). If "x scale 1.1 z volume" is specified and parameter {y} is unspecified, then the z box length will shrink as x increases to keep the product of x,z lengths constant. If "x scale 1.1 y volume z volume" is specified, then both the y,z box lengths will shrink as x increases to keep the volume constant (product of x,y,z lengths). In this case, the y,z box lengths shrink so as to keep their relative aspect ratio constant. For solids or liquids, note that when one dimension of the box is expanded via fix deform (i.e. tensile strain), it may be physically undesirable to hold the other 2 box lengths constant (unspecified by fix deform) since that implies a density change. Using the {volume} style for those 2 dimensions to keep the box volume constant may make more physical sense, but may also not be correct for materials and potentials whose Poisson ratio is not 0.5. An alternative is to use "fix npt aniso"_fix_nh.html with zero applied pressure on those 2 dimensions, so that they respond to the tensile strain dynamically. The {wiggle} style oscillates the specified box length dimension sinusoidally with the specified amplitude and period. I.e. the box length L as a function of time is given by L(t) = L0 + A sin(2*pi t/Tp) :pre where L0 is its initial length. If the amplitude A is a positive number the box initially expands, then contracts, etc. If A is negative then the box initially contracts, then expands, etc. The amplitude can be in lattice or box distance units. See the discussion of the units keyword below. The {variable} style changes the specified box length dimension by evaluating a variable, which presumably is a function of time. The variable with {name1} must be an "equal-style variable"_variable.html and should calculate a change in box length in units of distance. Note that this distance is in box units, not lattice units; see the discussion of the {units} keyword below. The formula associated with variable {name1} can reference the current timestep. Note that it should return the "change" in box length, not the absolute box length. This means it should evaluate to 0.0 when invoked on the initial timestep of the run following the definition of fix deform. It should evaluate to a value > 0.0 to dilate the box at future times, or a value < 0.0 to compress the box. The variable {name2} must also be an "equal-style variable"_variable.html and should calculate the rate of box length change, in units of distance/time, i.e. the time-derivative of the {name1} variable. This quantity is used internally by LAMMPS to reset atom velocities when they cross periodic boundaries. It is computed internally for the other styles, but you must provide it when using an arbitrary variable. Here is an example of using the {variable} style to perform the same box deformation as the {wiggle} style formula listed above, where we assume that the current timestep = 0. variable A equal 5.0 variable Tp equal 10.0 variable displace equal "v_A * sin(2*PI * step*dt/v_Tp)" variable rate equal "2*PI*v_A/v_Tp * cos(2*PI * step*dt/v_Tp)" fix 2 all deform 1 x variable v_displace v_rate remap v :pre For the {scale}, {vel}, {erate}, {trate}, {volume}, {wiggle}, and {variable} styles, the box length is expanded or compressed around its mid point. :line For the {xy}, {xz}, and {yz} parameters, this is the meaning of their styles and values. Note that changing the tilt factors of a triclinic box does not change its volume. The {final}, {delta}, {vel}, and {erate} styles all change the shear strain at a "constant engineering shear strain rate". This means the tilt factor changes linearly with time from its initial to final value. For style {final}, the final tilt factor is specified. The value can be in lattice or box distance units. See the discussion of the units keyword below. For style {delta}, a plus or minus change in the tilt factor is specified. The value can be in lattice or box distance units. See the discussion of the units keyword below. For style {vel}, a velocity at which the tilt factor changes is specified in units of distance/time. This is effectively an "engineering shear strain rate", where rate = V/L0 and L0 is the initial box length perpendicular to the direction of shear. The distance can be in lattice or box distance units. See the discussion of the units keyword below. For example, if the initial tilt factor is 5 Angstroms, and the V is 10 Angstroms/psec, then after 1 psec, the tilt factor will be 15 Angstroms. After 2 psec, it will be 25 Angstroms. The {erate} style changes a tilt factor at a "constant engineering shear strain rate". The units of the specified shear strain rate are 1/time. See the "units"_units.html command for the time units associated with different choices of simulation units, e.g. picoseconds for "metal" units). Shear strain is unitless and is defined as offset/length, where length is the box length perpendicular to the shear direction (e.g. y box length for xy deformation) and offset is the displacement distance in the shear direction (e.g. x direction for xy deformation) from the unstrained orientation. The tilt factor T as a function of time will change as T(t) = T0 + L0*erate*dt :pre where T0 is the initial tilt factor, L0 is the original length of the box perpendicular to the shear direction (e.g. y box length for xy deformation), and dt is the elapsed time (in time units). Thus if {erate} R is specified as 0.1 and time units are picoseconds, this means the shear strain will increase by 0.1 every picosecond. I.e. if the xy shear strain was initially 0.0, then strain after 1 psec = 0.1, strain after 2 psec = 0.2, etc. Thus the tilt factor would be 0.0 at time 0, 0.1*ybox at 1 psec, 0.2*ybox at 2 psec, etc, where ybox is the original y box length. R = 1 or 2 means the tilt factor will increase by 1 or 2 every picosecond. R = -0.01 means a decrease in shear strain by 0.01 every picosecond. The {trate} style changes a tilt factor at a "constant true shear strain rate". Note that this is not an "engineering shear strain rate", as the other styles are. Rather, for a "true" rate, the rate of change is constant, which means the tilt factor changes non-linearly with time from its initial to final value. The units of the specified shear strain rate are 1/time. See the "units"_units.html command for the time units associated with different choices of simulation units, e.g. picoseconds for "metal" units). Shear strain is unitless and is defined as offset/length, where length is the box length perpendicular to the shear direction (e.g. y box length for xy deformation) and offset is the displacement distance in the shear direction (e.g. x direction for xy deformation) from the unstrained orientation. The tilt factor T as a function of time will change as T(t) = T0 exp(trate*dt) :pre where T0 is the initial tilt factor and dt is the elapsed time (in time units). Thus if {trate} R is specified as ln(1.1) and time units are picoseconds, this means the shear strain or tilt factor will increase by 10% every picosecond. I.e. if the xy shear strain was initially 0.1, then strain after 1 psec = 0.11, strain after 2 psec = 0.121, etc. R = ln(2) or ln(3) means the tilt factor will double or triple every picosecond. R = ln(0.99) means the tilt factor will shrink by 1% every picosecond. Note that the change is continuous, so running with R = ln(2) for 10 picoseconds does not change the tilt factor by a factor of 10, but by a factor of 1024 since it doubles every picosecond. Note that the initial tilt factor must be non-zero to use the {trate} option. Note that shear strain is defined as the tilt factor divided by the perpendicular box length. The {erate} and {trate} styles control the tilt factor, but assume the perpendicular box length remains constant. If this is not the case (e.g. it changes due to another fix deform parameter), then this effect on the shear strain is ignored. The {wiggle} style oscillates the specified tilt factor sinusoidally with the specified amplitude and period. I.e. the tilt factor T as a function of time is given by T(t) = T0 + A sin(2*pi t/Tp) :pre where T0 is its initial value. If the amplitude A is a positive number the tilt factor initially becomes more positive, then more negative, etc. If A is negative then the tilt factor initially becomes more negative, then more positive, etc. The amplitude can be in lattice or box distance units. See the discussion of the units keyword below. The {variable} style changes the specified tilt factor by evaluating a variable, which presumably is a function of time. The variable with {name1} must be an "equal-style variable"_variable.html and should calculate a change in tilt in units of distance. Note that this distance is in box units, not lattice units; see the discussion of the {units} keyword below. The formula associated with variable {name1} can reference the current timestep. Note that it should return the "change" in tilt factor, not the absolute tilt factor. This means it should evaluate to 0.0 when invoked on the initial timestep of the run following the definition of fix deform. The variable {name2} must also be an "equal-style variable"_variable.html and should calculate the rate of tilt change, in units of distance/time, i.e. the time-derivative of the {name1} variable. This quantity is used internally by LAMMPS to reset atom velocities when they cross periodic boundaries. It is computed internally for the other styles, but you must provide it when using an arbitrary variable. Here is an example of using the {variable} style to perform the same box deformation as the {wiggle} style formula listed above, where we assume that the current timestep = 0. variable A equal 5.0 variable Tp equal 10.0 variable displace equal "v_A * sin(2*PI * step*dt/v_Tp)" variable rate equal "2*PI*v_A/v_Tp * cos(2*PI * step*dt/v_Tp)" fix 2 all deform 1 xy variable v_displace v_rate remap v :pre :line All of the tilt styles change the xy, xz, yz tilt factors during a simulation. In LAMMPS, tilt factors (xy,xz,yz) for triclinic boxes are normally bounded by half the distance of the parallel box length. See the discussion of the {flip} keyword below, to allow this bound to be exceeded, if desired. For example, if xlo = 2 and xhi = 12, then the x box length is 10 and the xy tilt factor must be between -5 and 5. Similarly, both xz and yz must be between -(xhi-xlo)/2 and +(yhi-ylo)/2. Note that this is not a limitation, since if the maximum tilt factor is 5 (as in this example), then configurations with tilt = ..., -15, -5, 5, 15, 25, ... are all equivalent. To obey this constraint and allow for large shear deformations to be applied via the {xy}, {xz}, or {yz} parameters, the following algorithm is used. If {prd} is the associated parallel box length (10 in the example above), then if the tilt factor exceeds the accepted range of -5 to 5 during the simulation, then the box is flipped to the other limit (an equivalent box) and the simulation continues. Thus for this example, if the initial xy tilt factor was 0.0 and "xy final 100.0" was specified, then during the simulation the xy tilt factor would increase from 0.0 to 5.0, the box would be flipped so that the tilt factor becomes -5.0, the tilt factor would increase from -5.0 to 5.0, the box would be flipped again, etc. The flip occurs 10 times and the final tilt factor at the end of the simulation would be 0.0. During each flip event, atoms are remapped into the new box in the appropriate manner. The one exception to this rule is if the 1st dimension in the tilt factor (x for xy) is non-periodic. In that case, the limits on the tilt factor are not enforced, since flipping the box in that dimension does not change the atom positions due to non-periodicity. In this mode, if you tilt the system to extreme angles, the simulation will simply become inefficient due to the highly skewed simulation box. :line Each time the box size or shape is changed, the {remap} keyword determines whether atom positions are remapped to the new box. If {remap} is set to {x} (the default), atoms in the fix group are remapped; otherwise they are not. Note that their velocities are not changed, just their positions are altered. If {remap} is set to {v}, then any atom in the fix group that crosses a periodic boundary will have a delta added to its velocity equal to the difference in velocities between the lo and hi boundaries. Note that this velocity difference can include tilt components, e.g. a delta in the x velocity when an atom crosses the y periodic boundary. If {remap} is set to {none}, then neither of these remappings take place. Conceptually, setting {remap} to {x} forces the atoms to deform via an affine transformation that exactly matches the box deformation. This setting is typically appropriate for solids. Note that though the atoms are effectively "moving" with the box over time, it is not due to their having a velocity that tracks the box change, but only due to the remapping. By contrast, setting {remap} to {v} is typically appropriate for fluids, where you want the atoms to respond to the change in box size/shape on their own and acquire a velocity that matches the box change, so that their motion will naturally track the box without explicit remapping of their coordinates. NOTE: When non-equilibrium MD (NEMD) simulations are performed using this fix, the option "remap v" should normally be used. This is because "fix nvt/sllod"_fix_nvt_sllod.html adjusts the atom positions and velocities to induce a velocity profile that matches the changing box size/shape. Thus atom coordinates should NOT be remapped by fix deform, but velocities SHOULD be when atoms cross periodic boundaries, since that is consistent with maintaining the velocity profile already created by fix nvt/sllod. LAMMPS will warn you if the {remap} setting is not consistent with fix nvt/sllod. NOTE: For non-equilibrium MD (NEMD) simulations using "remap v" it is usually desirable that the fluid (or flowing material, e.g. granular particles) stream with a velocity profile consistent with the deforming box. As mentioned above, using a thermostat such as "fix nvt/sllod"_fix_nvt_sllod.html or "fix lavgevin"_fix_langevin.html (with a bias provided by "compute temp/deform"_compute_temp_deform.html), will typically accomplish that. If you do not use a thermostat, then there is no driving force pushing the atoms to flow in a manner consistent with the deforming box. E.g. for a shearing system the box deformation velocity may vary from 0 at the bottom to 10 at the top of the box. But the stream velocity profile of the atoms may vary from -5 at the bottom to +5 at the top. You can monitor these effects using the "fix ave/chunk"_fix_ave_chunk.html, "compute temp/deform"_compute_temp_deform.html, and "compute temp/profile"_compute_temp_profile.html commands. One way to induce atoms to stream consistent with the box deformation is to give them an initial velocity profile, via the "velocity ramp"_velocity.html command, that matches the box deformation rate. This also typically helps the system come to equilibrium more quickly, even if a thermostat is used. NOTE: If a "fix rigid"_fix_rigid.html is defined for rigid bodies, and {remap} is set to {x}, then the center-of-mass coordinates of rigid bodies will be remapped to the changing simulation box. This will be done regardless of whether atoms in the rigid bodies are in the fix deform group or not. The velocity of the centers of mass are not remapped even if {remap} is set to {v}, since "fix nvt/sllod"_fix_nvt_sllod.html does not currently do anything special for rigid particles. If you wish to perform a NEMD simulation of rigid particles, you can either thermostat them independently or include a background fluid and thermostat the fluid via "fix nvt/sllod"_fix_nvt_sllod.html. The {flip} keyword allows the tilt factors for a triclinic box to exceed half the distance of the parallel box length, as discussed above. If the {flip} value is set to {yes}, the bound is enforced by flipping the box when it is exceeded. If the {flip} value is set to {no}, the tilt will continue to change without flipping. Note that if you apply large deformations, this means the box shape can tilt dramatically LAMMPS will run less efficiently, due to the large volume of communication needed to acquire ghost atoms around a processor's irregular-shaped sub-domain. For extreme values of tilt, LAMMPS may also lose atoms and generate an error. The {units} keyword determines the meaning of the distance units used to define various arguments. A {box} value selects standard distance units as defined by the "units"_units.html command, e.g. Angstroms for units = real or metal. A {lattice} value means the distance units are in lattice spacings. The "lattice"_lattice.html command must have been previously used to define the lattice spacing. Note that the units choice also affects the {vel} style parameters since it is defined in terms of distance/time. Also note that the units keyword does not affect the {variable} style. You should use the {xlat}, {ylat}, {zlat} keywords of the "thermo_style"_thermo_style.html command if you want to include lattice spacings in a variable formula. :line Styles with a {gpu}, {intel}, {kk}, {omp}, or {opt} suffix are functionally the same as the corresponding style without the suffix. They have been optimized to run faster, depending on your available hardware, as discussed in "Section 5"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. These accelerated styles are part of the GPU, USER-INTEL, KOKKOS, USER-OMP and OPT packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. You can specify the accelerated styles explicitly in your input script by including their suffix, or you can use the "-suffix command-line switch"_Section_start.html#start_7 when you invoke LAMMPS, or you can use the "suffix"_suffix.html command in your input script. See "Section 5"_Section_accelerate.html of the manual for more instructions on how to use the accelerated styles effectively. [Restart, fix_modify, output, run start/stop, minimize info:] No information about this fix is written to "binary restart files"_restart.html. None of the "fix_modify"_fix_modify.html options are relevant to this fix. No global or per-atom quantities are stored by this fix for access by various "output commands"_Section_howto.html#howto_15. This fix can perform deformation over multiple runs, using the {start} and {stop} keywords of the "run"_run.html command. See the "run"_run.html command for details of how to do this. This fix is not invoked during "energy minimization"_minimize.html. [Restrictions:] You cannot apply x, y, or z deformations to a dimension that is shrink-wrapped via the "boundary"_boundary.html comamnd. You cannot apply xy, yz, or xz deformations to a 2nd dimension (y in xy) that is shrink-wrapped via the "boundary"_boundary.html comamnd. [Related commands:] "change_box"_change_box.html [Default:] The option defaults are remap = x, flip = yes, and units = lattice. diff --git a/doc/src/fix_flow_gauss.txt b/doc/src/fix_flow_gauss.txt index 538a362c5..e4088cd02 100644 --- a/doc/src/fix_flow_gauss.txt +++ b/doc/src/fix_flow_gauss.txt @@ -1,142 +1,160 @@ "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 fix flow/gauss command :h3 [Syntax:] fix ID group-ID flow/gauss xflag yflag zflag keyword :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l flow/gauss = style name of this fix command :l xflag,yflag,zflag = 0 or 1 :l 0 = do not conserve current in this dimension 1 = conserve current in this dimension :pre zero or more keyword/value pairs may be appended :l keyword = {energy} :l {energy} value = no or yes no = do not compute work done by this fix yes = compute work done by this fix :pre :ule [Examples:] fix GD fluid flow/gauss 1 0 0 fix GD fluid flow/gauss 1 1 1 energy yes :pre [Description:] This fix implements the Gaussian dynamics (GD) method to simulate a system at constant mass flux "(Strong)"_#Strong. GD is a nonequilibrium molecular dynamics simulation method that can be used to study fluid flows through pores, pipes, and channels. In its original implementation GD was used to compute the pressure required to achieve a fixed mass flux through an opening. The flux can be conserved in any combination of the directions, x, y, or z, using xflag,yflag,zflag. This fix does not initialize a net flux through a system, it only conserves the center-of-mass momentum that is present when the fix is declared in the input script. Use the "velocity"_velocity.html command to generate an initial center-of-mass momentum. GD applies an external fluctuating gravitational field that acts as a driving force to keep the system away from equilibrium. To maintain steady state, a profile-unbiased thermostat must be implemented to dissipate the heat that is added by the driving force. "Compute temp/profile"_compute_temp_profile.html can be used to implement a profile-unbiased thermostat. A common use of this fix is to compute a pressure drop across a pipe, pore, or membrane. The pressure profile can be computed in LAMMPS with "compute stress/atom"_compute_stress_atom.html and "fix ave/chunk"_fix_ave_chunk.html, or with the hardy method in "fix atc"_fix_atc.html. Note that the simple "compute stress/atom"_compute_stress_atom.html method is only accurate away from inhomogeneities in the fluid, such as fixed wall atoms. Further, the computed pressure profile must be corrected for the acceleration applied by GD before computing a pressure drop or comparing it to other methods, such as the pump method "(Zhu)"_#Zhu. The pressure correction is discussed and described in "(Strong)"_#Strong. -NOTE: For a complete example including the considerations discussed +For a complete example including the considerations discussed above, see the examples/USER/flow_gauss directory. NOTE: Only the flux of the atoms in group-ID will be conserved. If the velocities of the group-ID atoms are coupled to the velocities of other atoms in the simulation, the flux will not be conserved. For example, in a simulation with fluid atoms and harmonically constrained wall atoms, if a single thermostat is applied to group {all}, the fluid atom velocities will be coupled to the wall atom velocities, and the flux will not be conserved. This issue can be avoided by thermostatting the fluid and wall groups separately. Adding an acceleration to atoms does work on the system. This added energy can be optionally subtracted from the potential energy for the thermodynamic output (see below) to check that the timestep is small enough to conserve energy. Since the applied acceleration is fluctuating in time, the work cannot be computed from a potential. As a result, computing the work is slightly more computationally expensive than usual, so it is not performed by default. To invoke the work calculation, use the {energy} keyword. The "fix_modify"_fix_modify.html {energy} option also invokes the work calculation, and overrides an {energy no} setting here. If neither {energy yes} or {fix_modify energy yes} are set, the global scalar computed by the fix will return zero. NOTE: In order to check energy conservation, any other fixes that do work on the system must have {fix_modify energy yes} set as well. This includes thermostat fixes and any constraints that hold the positions of wall atoms fixed, such as "fix spring/self"_fix_spring_self.html. +If this fix is used in a simulation with the "rRESPA"_run_style.html +integrator, the applied acceleration must be computed and applied at the same +rRESPA level as the interactions between the flowing fluid and the obstacle. +The rRESPA level at which the acceleration is applied can be changed using +the "fix_modify"_fix_modify.html {respa} option discussed below. If the +flowing fluid and the obstacle interact through multiple interactions that are +computed at different rRESPA levels, then there must be a separate flow/gauss +fix for each level. For example, if the flowing fluid and obstacle interact +through pairwise and long-range Coulomb interactions, which are computed at +rRESPA levels 3 and 4, respectively, then there must be two separate +flow/gauss fixes, one that specifies {fix_modify respa 3} and one with +{fix_modify respa 4}. + :line [Restart, fix_modify, output, run start/stop, minimize info:] This fix is part of the USER-MISC 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. No information about this fix is written to "binary restart files"_restart.html. The "fix_modify"_fix_modify.html {energy} option is supported by this fix to subtract the work done from the system's potential energy as part of "thermodynamic output"_thermo_style.html. +The "fix_modify"_fix_modify.html {respa} option is supported by this +fix. This allows the user to set at which level of the "rRESPA"_run_style.html +integrator the fix computes and adds the external acceleration. Default is the +outermost level. + This fix computes a global scalar and a global 3-vector of forces, which can be accessed by various "output commands"_Section_howto.html#howto_15. The scalar is the negative of the work done on the system, see above discussion. The vector is the total force that this fix applied to the group of atoms on the current timestep. The scalar and vector values calculated by this fix are "extensive". No parameter of this fix can be used with the {start/stop} keywords of the "run"_run.html command. [Restrictions:] none [Related commands:] "fix addforce"_fix_addforce.html, "compute temp/profile"_compute_temp_profile.html, "velocity"_velocity.html [Default:] The option default for the {energy} keyword is energy = no. :line :link(Strong) [(Strong)] Strong and Eaves, J. Phys. Chem. Lett. 7, 1907 (2016). :link(Evans) [(Evans)] Evans and Morriss, Phys. Rev. Lett. 56, 2172 (1986). :link(Zhu) [(Zhu)] Zhu, Tajkhorshid, and Schulten, Biophys. J. 83, 154 (2002). diff --git a/doc/src/fix_lb_fluid.txt b/doc/src/fix_lb_fluid.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_lb_momentum.txt b/doc/src/fix_lb_momentum.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_lb_pc.txt b/doc/src/fix_lb_pc.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_lb_rigid_pc_sphere.txt b/doc/src/fix_lb_rigid_pc_sphere.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_lb_viscous.txt b/doc/src/fix_lb_viscous.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_msst.txt b/doc/src/fix_msst.txt index fb47f9a0a..bd1edd805 100644 --- a/doc/src/fix_msst.txt +++ b/doc/src/fix_msst.txt @@ -1,158 +1,158 @@ "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 fix msst command :h3 [Syntax:] fix ID group-ID msst dir shockvel keyword value ... :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l msst = style name of this fix :l dir = {x} or {y} or {z} :l shockvel = shock velocity (strictly positive, distance/time units) :l zero or more keyword value pairs may be appended :l keyword = {q} or {mu} or {p0} or {v0} or {e0} or {tscale} :l {q} value = cell mass-like parameter (mass^2/distance^4 units) {mu} value = artificial viscosity (mass/length/time units) {p0} value = initial pressure in the shock equations (pressure units) {v0} value = initial simulation cell volume in the shock equations (distance^3 units) {e0} value = initial total energy (energy units) {tscale} value = reduction in initial temperature (unitless fraction between 0.0 and 1.0) :pre :ule [Examples:] fix 1 all msst y 100.0 q 1.0e5 mu 1.0e5 fix 2 all msst z 50.0 q 1.0e4 mu 1.0e4 v0 4.3419e+03 p0 3.7797e+03 e0 -9.72360e+02 tscale 0.01 :pre [Description:] This command performs the Multi-Scale Shock Technique (MSST) integration to update positions and velocities each timestep to mimic a compressive shock wave passing over the system. See "(Reed)"_#Reed for a detailed description of this method. The MSST varies the cell volume and temperature in such a way as to restrain the system to the shock Hugoniot and the Rayleigh line. These restraints correspond to the macroscopic conservation laws dictated by a shock front. {shockvel} determines the steady shock velocity that will be simulated. To perform a simulation, choose a value of {q} that provides volume compression on the timescale of 100 fs to 1 ps. If the volume is not compressing, either the shock speed is chosen to be below the material sound speed or {p0} has been chosen inaccurately. Volume compression at the start can be sped up by using a non-zero value of {tscale}. Use the smallest value of {tscale} that results in compression. Under some special high-symmetry conditions, the pressure (volume) and/or temperature of the system may oscillate for many cycles even with an appropriate choice of mass-like parameter {q}. Such oscillations have physical significance in some cases. The optional {mu} keyword adds an artificial viscosity that helps break the system symmetry to equilibrate to the shock Hugoniot and Rayleigh line more rapidly in such cases. {tscale} is a factor between 0 and 1 that determines what fraction of thermal kinetic energy is converted to compressive strain kinetic energy at the start of the simulation. Setting this parameter to a non-zero value may assist in compression at the start of simulations where it is slow to occur. If keywords {e0}, {p0},or {v0} are not supplied, these quantities will be calculated on the first step, after the energy specified by {tscale} is removed. The value of {e0} is not used in the dynamical equations, but is used in calculating the deviation from the Hugoniot. Values of shockvel less than a critical value determined by the material response will not have compressive solutions. This will be reflected in lack of significant change of the volume in the MSST. For all pressure styles, the simulation box stays orthogonal in shape. Parrinello-Rahman boundary conditions (tilted box) are supported by LAMMPS, but are not implemented for MSST. This fix computes a temperature and pressure each timestep. To do this, the fix creates its own computes of style "temp" and "pressure", as if these commands had been issued: compute fix-ID_temp group-ID temp compute fix-ID_press group-ID pressure fix-ID_temp :pre See the "compute temp"_compute_temp.html and "compute pressure"_compute_pressure.html commands for details. Note that the IDs of the new computes are the fix-ID + underscore + "temp" or fix_ID + underscore + "press". The group for the new computes is "all". [Restart, fix_modify, output, run start/stop, minimize info:] This fix writes the state of all internal variables to "binary restart files"_restart.html. See the "read_restart"_read_restart.html command for info on how to re-specify a fix in an input script that reads a restart file, so that the operation of the fix continues in an uninterrupted fashion. The progress of the MSST can be monitored by printing the global scalar and global vector quantities computed by the fix. The scalar is the cumulative energy change due to the fix. This is also the energy added to the potential energy by the "fix_modify"_fix_modify.html {energy} command. With this command, the thermo keyword {etotal} prints the conserved quantity of the MSST dynamic equations. This can be used to test if the MD timestep is sufficiently small for accurate integration of the dynamic equations. See also "thermo_style"_thermo_style.html command. The global vector contains four values in this order: \[{dhugoniot}, {drayleigh}, {lagrangian_speed}, {lagrangian_position}\] {dhugoniot} is the departure from the Hugoniot (temperature units). {drayleigh} is the departure from the Rayleigh line (pressure units). {lagrangian_speed} is the laboratory-frame Lagrangian speed (particle velocity) of the computational cell (velocity units). {lagrangian_position} is the computational cell position in the reference frame moving at the shock speed. This is usually a good estimate of distance of the computational cell behind the shock front. :ol To print these quantities to the log file with descriptive column headers, the following LAMMPS commands are suggested: -fix msst all msst z +fix msst all msst z fix_modify msst energy yes variable dhug equal f_msst\[1\] variable dray equal f_msst\[2\] variable lgr_vel equal f_msst\[3\] variable lgr_pos equal f_msst\[4\] thermo_style custom step temp ke pe lz pzz etotal v_dhug v_dray v_lgr_vel v_lgr_pos f_msst :pre These fixes compute a global scalar and a global vector of 4 quantities, which can be accessed by various "output commands"_Section_howto.html#howto_15. The scalar values calculated by this fix are "extensive"; the vector values are "intensive". [Restrictions:] This fix style is part of the SHOCK 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. All cell dimensions must be periodic. This fix can not be used with a triclinic cell. The MSST fix has been tested only for the group-ID all. [Related commands:] "fix nphug"_fix_nphug.html, "fix deform"_fix_deform.html [Default:] The keyword defaults are q = 10, mu = 0, tscale = 0.01. p0, v0, and e0 are calculated on the first step. :line :link(Reed) [(Reed)] Reed, Fried, and Joannopoulos, Phys. Rev. Lett., 90, 235503 (2003). diff --git a/doc/src/fix_nph_asphere.txt b/doc/src/fix_nph_asphere.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_nph_body.txt b/doc/src/fix_nph_body.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_nph_sphere.txt b/doc/src/fix_nph_sphere.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_npt_asphere.txt b/doc/src/fix_npt_asphere.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_npt_body.txt b/doc/src/fix_npt_body.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_npt_sphere.txt b/doc/src/fix_npt_sphere.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_nve_asphere.txt b/doc/src/fix_nve_asphere.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_nve_asphere_noforce.txt b/doc/src/fix_nve_asphere_noforce.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_nve_body.txt b/doc/src/fix_nve_body.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_nve_line.txt b/doc/src/fix_nve_line.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_nve_sphere.txt b/doc/src/fix_nve_sphere.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_nve_tri.txt b/doc/src/fix_nve_tri.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_nvt_asphere.txt b/doc/src/fix_nvt_asphere.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_nvt_body.txt b/doc/src/fix_nvt_body.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_nvt_sphere.txt b/doc/src/fix_nvt_sphere.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_qbmsst.txt b/doc/src/fix_qbmsst.txt index 7979a8fae..468206a57 100644 --- a/doc/src/fix_qbmsst.txt +++ b/doc/src/fix_qbmsst.txt @@ -1,219 +1,219 @@ "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 fix qbmsst command :h3 [Syntax:] fix ID group-ID qbmsst dir shockvel keyword value ... :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l qbmsst = style name of this fix :l dir = {x} or {y} or {z} :l shockvel = shock velocity (strictly positive, velocity units) :l zero or more keyword/value pairs may be appended :l keyword = {q} or {mu} or {p0} or {v0} or {e0} or {tscale} or {damp} or {seed}or {f_max} or {N_f} or {eta} or {beta} or {T_init} :l {q} value = cell mass-like parameter (mass^2/distance^4 units) {mu} value = artificial viscosity (mass/distance/time units) {p0} value = initial pressure in the shock equations (pressure units) {v0} value = initial simulation cell volume in the shock equations (distance^3 units) {e0} value = initial total energy (energy units) {tscale} value = reduction in initial temperature (unitless fraction between 0.0 and 1.0) {damp} value = damping parameter (time units) inverse of friction γ {seed} value = random number seed (positive integer) {f_max} value = upper cutoff frequency of the vibration spectrum (1/time units) {N_f} value = number of frequency bins (positive integer) {eta} value = coupling constant between the shock system and the quantum thermal bath (positive unitless) {beta} value = the quantum temperature is updated every beta time steps (positive integer) {T_init} value = quantum temperature for the initial state (temperature units) :pre :ule [Examples:] fix 1 all qbmsst z 0.122 q 25 mu 0.9 tscale 0.01 damp 200 seed 35082 f_max 0.3 N_f 100 eta 1 beta 400 T_init 110 (liquid methane modeled with the REAX force field, real units) fix 2 all qbmsst z 72 q 40 tscale 0.05 damp 1 seed 47508 f_max 120.0 N_f 100 eta 1.0 beta 500 T_init 300 (quartz modeled with the BKS force field, metal units) :pre Two example input scripts are given, including shocked alpha quartz and shocked liquid methane. The input script first equilibrate an initial state with the quantum thermal bath at the target temperature and then apply the qbmsst to simulate shock compression with quantum nuclear correction. The following two figures plot related quantities for shocked alpha quartz. :c,image(JPG/qbmsst_init.jpg) Figure 1. Classical temperature Tcl = ∑ mivi2/3NkB vs. time for coupling the alpha quartz initial state with the quantum thermal bath at target quantum temperature Tqm = 300 K. The NpH ensemble is used for time integration while QTB provides the colored random force. Tcl converges at the timescale of {damp} which is set to be 1 ps. :c,image(JPG/qbmsst_shock.jpg) Figure 2. Quantum temperature and pressure vs. time for simulating shocked alpha quartz with the QBMSST. The shock propagates along the z direction. Restart of the QBMSST command is demonstrated in the example input script. Thermodynamic quantities stay continuous before and after the restart. [Description:] This command performs the Quantum-Bath coupled Multi-Scale Shock Technique (QBMSST) integration. See "(Qi)"_#Qi for a detailed description of this method. The QBMSST provides description of the thermodynamics and kinetics of shock processes while incorporating quantum nuclear effects. The {shockvel} setting determines the steady shock velocity that will be simulated along direction {dir}. Quantum nuclear effects "(fix qtb)"_fix_qtb.html can be crucial especially when the temperature of the initial state is below the classical limit or there is a great change in the zero point energies between the initial and final states. Theoretical post processing quantum corrections of shock compressed water and methane have been reported as much as 30% of the temperatures "(Goldman)"_#Goldman. A self-consistent method that couples the shock to a quantum thermal bath described by a colored noise Langevin thermostat has been developed by Qi et al "(Qi)"_#Qi and applied to shocked methane. The onset of chemistry is reported to be at a pressure on the shock Hugoniot that is 40% lower than observed with classical molecular dynamics. It is highly recommended that the system be already in an equilibrium state with a quantum thermal bath at temperature of {T_init}. The fix command "fix qtb"_fix_qtb.html at constant temperature {T_init} could be used before applying this command to introduce self-consistent quantum nuclear effects into the initial state. The parameters {q}, {mu}, {e0}, {p0}, {v0} and {tscale} are described in the command "fix msst"_fix_msst.html. The values of {e0}, {p0}, or {v0} will be calculated on the first step if not specified. The parameter of {damp}, {f_max}, and {N_f} are described in the command "fix qtb"_fix_qtb.html. The fix qbmsst command couples the shock system to a quantum thermal bath with a rate that is proportional to the change of the total energy of the shock system, etot - etot0. Here etot consists of both the system energy and a thermal term, see "(Qi)"_#Qi, and etot0 = {e0} is the initial total energy. The {eta} (η) parameter is a unitless coupling constant between the shock system and the quantum thermal bath. A small {eta} value cannot adjust the quantum temperature fast enough during the temperature ramping period of shock compression while large {eta} leads to big temperature oscillation. A value of {eta} between 0.3 and 1 is usually appropriate for simulating most systems under shock compression. We observe that different values of {eta} lead to almost the same final thermodynamic state behind the shock, as expected. The quantum temperature is updated every {beta} (β) steps with an integration time interval {beta} times longer than the simulation time step. In that case, etot is taken as its average over the past {beta} steps. The temperature of the quantum thermal bath Tqm changes dynamically according to the following equation where Δt is the MD time step and γ is the friction constant which is equal to the inverse of the {damp} parameter.
dTqm/dt = γηβl = 1[etot(t-lΔt)-etot0]/3βNkB
The parameter {T_init} is the initial temperature of the quantum thermal bath and the system before shock loading. For all pressure styles, the simulation box stays orthorhombic in shape. Parrinello-Rahman boundary conditions (tilted box) are supported by LAMMPS, but are not implemented for QBMSST. :line [Restart, fix_modify, output, run start/stop, minimize info:] Because the state of the random number generator is not written to "binary restart files"_restart.html, this fix cannot be restarted "exactly" in an uninterrupted fashion. However, in a statistical sense, a restarted simulation should produce similar behaviors of the system as if it is not interrupted. To achieve such a restart, one should write explicitly the same value for {q}, {mu}, {damp}, {f_max}, {N_f}, {eta}, and {beta} and set {tscale} = 0 if the system is compressed during the first run. The progress of the QBMSST can be monitored by printing the global scalar and global vector quantities computed by the fix. The global vector contains five values in this order: \[{dhugoniot}, {drayleigh}, {lagrangian_speed}, {lagrangian_position}, {quantum_temperature}\] {dhugoniot} is the departure from the Hugoniot (temperature units). {drayleigh} is the departure from the Rayleigh line (pressure units). {lagrangian_speed} is the laboratory-frame Lagrangian speed (particle velocity) of the computational cell (velocity units). {lagrangian_position} is the computational cell position in the reference frame moving at the shock speed. This is the distance of the computational cell behind the shock front. {quantum_temperature} is the temperature of the quantum thermal bath Tqm. :ol To print these quantities to the log file with descriptive column headers, the following LAMMPS commands are suggested. Here the "fix_modify"_fix_modify.html energy command is also enabled to allow the thermo keyword {etotal} to print the quantity etot. See also the "thermo_style"_thermo_style.html command. -fix fix_id all msst z -fix_modify fix_id energy yes -variable dhug equal f_fix_id\[1\] -variable dray equal f_fix_id\[2\] -variable lgr_vel equal f_fix_id\[3\] -variable lgr_pos equal f_fix_id\[4\] -variable T_qm equal f_fix_id\[5\] -thermo_style custom step temp ke pe lz pzz etotal v_dhug v_dray v_lgr_vel v_lgr_pos v_T_qm f_fix_id :pre +fix fix_id all msst z +fix_modify fix_id energy yes +variable dhug equal f_fix_id\[1\] +variable dray equal f_fix_id\[2\] +variable lgr_vel equal f_fix_id\[3\] +variable lgr_pos equal f_fix_id\[4\] +variable T_qm equal f_fix_id\[5\] +thermo_style custom step temp ke pe lz pzz etotal v_dhug v_dray v_lgr_vel v_lgr_pos v_T_qm f_fix_id :pre The global scalar under the entry f_fix_id is the quantity of thermo energy as an extra part of etot. This global scalar and the vector of 5 quantities can be accessed by various "output commands"_Section_howto.html#howto_15. It is worth noting that the temp keyword under the "thermo_style"_thermo_style.html command print the instantaneous classical temperature Tcl as described in the command "fix qtb"_fix_qtb.html. :line [Restrictions:] This fix style is part of the USER-QTB 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. All cell dimensions must be periodic. This fix can not be used with a triclinic cell. The QBMSST fix has been tested only for the group-ID all. :line [Related commands:] "fix qtb"_fix_qtb.html, "fix msst"_fix_msst.html :line [Default:] The keyword defaults are q = 10, mu = 0, tscale = 0.01, damp = 1, seed = 880302, f_max = 200.0, N_f = 100, eta = 1.0, beta = 100, and T_init=300.0. e0, p0, and v0 are calculated on the first step. :line :link(Goldman) [(Goldman)] Goldman, Reed and Fried, J. Chem. Phys. 131, 204103 (2009) :link(Qi) [(Qi)] Qi and Reed, J. Phys. Chem. A 116, 10451 (2012). diff --git a/doc/src/fix_rx.txt b/doc/src/fix_rx.txt index bc185f768..4e26274b3 100644 --- a/doc/src/fix_rx.txt +++ b/doc/src/fix_rx.txt @@ -1,203 +1,203 @@ "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 fix rx command :h3 [Syntax:] fix ID group-ID rx file localTemp matrix solver minSteps ... :pre ID, group-ID are documented in "fix"_fix.html command rx = style name of this fix command file = filename containing the reaction kinetic equations and Arrhenius parameters localTemp = {none,lucy} = no local temperature averaging or local temperature defined through Lucy weighting function matrix = {sparse, dense} format for the stoichiometric matrix solver = {lammps_rk4,rkf45} = rk4 is an explicit 4th order Runge-Kutta method; rkf45 is an adaptive 4th-order Runge-Kutta-Fehlberg method minSteps = # of steps for rk4 solver or minimum # of steps for rkf45 (rk4 or rkf45) maxSteps = maximum number of steps for the rkf45 solver (rkf45 only) relTol = relative tolerance for the rkf45 solver (rkf45 only) absTol = absolute tolernace for the rkf45 solver (rkf45 only) diag = Diagnostics frequency for the rkf45 solver (optional, rkf45 only) :ul [Examples:] fix 1 all rx kinetics.rx none dense lammps_rk4 fix 1 all rx kinetics.rx none sparse lammps_rk4 1 fix 1 all rx kinetics.rx lucy sparse lammps_rk4 10 fix 1 all rx kinetics.rx none dense rkf45 1 100 1e-6 1e-8 fix 1 all rx kinetics.rx none dense rkf45 1 100 1e-6 1e-8 -1 :pre [Description:] Fix {rx} solves the reaction kinetic ODEs for a given reaction set that is defined within the file associated with this command. For a general reaction such that :c,image(Eqs/fix_rx_reaction.jpg) the reaction rate equation is defined to be of the form :c,image(Eqs/fix_rx_reactionRate.jpg) In the current implementation, the exponents are defined to be equal to the stoichiometric coefficients. A given reaction set consisting of {n} reaction equations will contain a total of {m} species. A set of {m} ordinary differential equations (ODEs) that describe the change in concentration of a given species as a function of time are then constructed based on the {n} reaction rate equations. The ODE systems are solved over the full DPD timestep {dt} using either a 4th order Runge-Kutta {rk4} method with a fixed step-size {h}, specified by the {lammps_rk4} keyword, or a 4th order Runge-Kutta-Fehlberg (rkf45) method with an adaptive step-size for {h}. The number of ODE steps per DPD timestep for the rk4 method is optionally specified immediately after the rk4 keyword. The ODE step-size is set as {dt/num_steps}. Smaller step-sizes tend to yield more accurate results but there is not control on the error. For error control, use the rkf45 ODE solver. The rkf45 method adjusts the step-size so that the local truncation error is held within the specified absolute and relative tolerances. The initial step-size {h0} can be specified by the user or estimated internally. It is recommeded that the user specify {h0} since this will generally reduced the number of ODE integration steps required. {h0} is defined as {dt / min_steps} if min_steps >= 1. If min_steps == 0, {h0} is estimated such that an explicit Euler method would likely produce an acceptable solution. This is generally overly conservative for the 4th-order method and users are advised to specify {h0} as some fraction of the DPD timestep. For small DPD timesteps, only one step may be necessary depending upon the tolerances. Note that more than min_steps ODE steps may be taken depending upon the ODE stiffness but no more than max_steps will be taken. If max_steps is reached, an error warning is printed and the simulation is stopped. After each ODE step, the solution error {e} is tested and weighted using the absTol -and relTol values. The error vector is weighted as {e} / (relTol * | {u} | + absTol) +and relTol values. The error vector is weighted as {e} / (relTol * |{u}| + absTol) where {u} is the solution vector. If the norm of the error is <= 1, the solution is accepted, {h} is increased by a proportional amount, and the next ODE step is begun. Otherwise, {h} is shrunk and the ODE step is repeated. Run-time diagnostics are available for the rkf45 ODE solver. The frequency (in time-steps) that diagnostics are reported is controlled by the last (optional) 12th argument. A negative frequency means that diagnostics are reported once at the end of each run. A positive value N means that the diagnostics are reported once per N time-steps. The diagnostics report the average # of integrator steps and RHS function evaluations and run-time per ODE as well as the the average/RMS/min/max per process. If the reporting frequency is 1, the RMS/min/max per ODE are also reported. The per ODE statistics can be used to adjust the tolerance and min/max step parameters. The statistics per MPI process can be useful to examine any load imbalance caused by the adaptive ODE solver. (Some DPD particles can take longer to solve than others. This can lead to an imbalance across the MPI processes.) :line The filename specifies a file that contains the entire set of reaction kinetic equations and corresponding Arrhenius parameters. The format of this file is described below. There is no restriction on the total number or reaction equations that are specified. The species names are arbitrary string names that are associated with the species concentrations. Each species in a given reaction must be preceded by it's stoichiometric coefficient. The only delimiters that are recognized between the species are either a {+} or {=} character. The {=} character corresponds to an irreversible reaction. After specifying the reaction, the reaction rate constant is determined through the temperature dependent Arrhenius equation: :c,image(Eqs/fix_rx.jpg) where {A} is the Arrhenius factor in time units or concentration/time units, {n} is the unitless exponent of the temperature dependence, and {E_a} is the activation energy in energy units. The temperature dependence can be removed by specifying the exponent as zero. The internal temperature of the coarse-grained particles can be used in constructing the reaction rate constants at every DPD timestep by specifying the keyword {none}. Alternatively, the keyword {lucy} can be specified to compute a local-average particle internal temperature for use in the reaction rate constant expressions. The local-average particle internal temperature is defined as: :c,image(Eqs/fix_rx_localTemp.jpg) where the Lucy function is expressed as: :c,image(Eqs/fix_rx_localTemp2.jpg) The self-particle interaction is included in the above equation. The stoichiometric coefficients for the reaction mechanism are stored in either a sparse or dense matrix format. The dense matrix should only be used for small reaction mechanisms. The sparse matrix should be used when there are many reactions (e.g., more than 5). This allows the number of reactions and species to grow while keeping the computational cost tractable. The matrix format can be specified as using either the {sparse} or {dense} keywords. If all stoichiometric coefficients for a reaction are small integers (whole numbers <= 3), a fast exponential function is used. This can save significant computational time so users are encouraged to use integer coefficients where possible. :line The format of a tabulated file is as follows (without the parenthesized comments): # Rxn equations and parameters (one or more comment or blank lines) :pre 1.0 hcn + 1.0 no2 = 1.0 no + 0.5 n2 + 0.5 h2 + 1.0 co 2.49E+01 0.0 1.34 (rxn equation, A, n, Ea) 1.0 hcn + 1.0 no = 1.0 co + 1.0 n2 + 0.5 h2 2.16E+00 0.0 1.52 ... 1.0 no + 1.0 co = 0.5 n2 + 1.0 co2 1.66E+06 0.0 0.69 :pre A section begins with a non-blank line whose 1st character is not a "#"; blank lines or lines starting with "#" can be used as comments between sections. Following a blank line, the next N lines list the N reaction equations. Each species within the reaction equation is specified through its stoichiometric coefficient and a species tag. Reactant species are specified on the left-hand side of the equation and product species are specified on the right-hand side of the equation. After specifying the reactant and product species, the final three arguments of each line represent the Arrhenius parameter {A}, the temperature exponent {n}, and the activation energy {Ea}. Note that the species tags that are defined in the reaction equations are used by the "fix eos/table/rx"_fix_eos_table_rx.html command to define the thermodynamic properties of each species. Furthermore, the number of species molecules (i.e., concentration) can be specified either with the "set"_set.html command using the "d_" prefix or by reading directly the concentrations from a data file. For the latter case, the "read_data"_read_data.html command with the fix keyword should be specified, where the fix-ID will be the "fix rx" ID with a "_SPECIES" suffix, e.g. fix foo all rx reaction.file ... read_data data.dpd fix foo_SPECIES NULL Species :line [Restrictions:] This command is part of the USER-DPD 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. This command also requires use of the "atom_style dpd"_atom_style.html command. This command can only be used with a constant energy or constant enthalpy DPD simulation. [Related commands:] "fix eos/table/rx"_fix_eos_table_rx.html, "fix shardlow"_fix_shardlow.html, "pair dpd/fdt/energy"_pair_dpd_fdt.html [Default:] none diff --git a/doc/src/fix_shake.txt b/doc/src/fix_shake.txt index 349b3a33d..4f63556c5 100644 --- a/doc/src/fix_shake.txt +++ b/doc/src/fix_shake.txt @@ -1,227 +1,227 @@ "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 fix shake command :h3 fix rattle command :h3 [Syntax:] fix ID group-ID style tol iter N constraint values ... keyword value ... :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l style = shake or rattle = style name of this fix command :l tol = accuracy tolerance of SHAKE solution :l iter = max # of iterations in each SHAKE solution :l N = print SHAKE statistics every this many timesteps (0 = never) :l one or more constraint/value pairs are appended :l constraint = {b} or {a} or {t} or {m} :l {b} values = one or more bond types {a} values = one or more angle types {t} values = one or more atom types {m} value = one or more mass values :pre zero or more keyword/value pairs may be appended :l keyword = {mol} :l {mol} value = template-ID template-ID = ID of molecule template specified in a separate "molecule"_molecule.html command :pre :ule [Examples:] fix 1 sub shake 0.0001 20 10 b 4 19 a 3 5 2 fix 1 sub shake 0.0001 20 10 t 5 6 m 1.0 a 31 fix 1 sub shake 0.0001 20 10 t 5 6 m 1.0 a 31 mol myMol fix 1 sub rattle 0.0001 20 10 t 5 6 m 1.0 a 31 fix 1 sub rattle 0.0001 20 10 t 5 6 m 1.0 a 31 mol myMol :pre [Description:] Apply bond and angle constraints to specified bonds and angles in the simulation by either the SHAKE or RATTLE algorithms. This typically enables a longer timestep. [SHAKE vs RATTLE:] The SHAKE algorithm was invented for schemes such as standard Verlet timesteppnig, where only the coordinates are integrated and the velocities are approximated as finite differences to the trajectories ("Ryckaert et al. (1977)"_#Ryckaert). If the velocities are integrated explicitly, as with velocity Verlet which is what LAMMPS uses as an integration method, a second set of constraining forces is required in order to eliminate velocity components along the bonds ("Andersen (1983)"_#Andersen). In order to formulate individual constraints for SHAKE and RATTLE, focus on a single molecule whose bonds are constrained. Let Ri and Vi be the position and velocity of atom {i} at time {n}, for {i}=1,...,{N}, where {N} is the number of sites of our reference molecule. The distance vector between sites {i} and {j} is given by :c,image(Eqs/fix_rattle_rij.jpg) The constraints can then be formulated as :c,image(Eqs/fix_rattle_constraints.jpg) The SHAKE algorithm satisfies the first condition, i.e. the sites at time {n+1} will have the desired separations Dij immediately after the coordinates are integrated. If we also enforce the second condition, the velocity components along the bonds will vanish. RATTLE satisfies both conditions. As implemented in LAMMPS, fix rattle uses fix shake for satisfying the coordinate constraints. Therefore the settings and optional keywords are the same for both fixes, and all the information below about SHAKE is also relevant for RATTLE. [SHAKE:] Each timestep the specified bonds and angles are reset to their equilibrium lengths and angular values via the SHAKE algorithm ("Ryckaert et al. (1977)"_#Ryckaert). This is done by applying an additional constraint force so that the new positions preserve the desired atom separations. The equations for the additional force are solved via an iterative method that typically converges to an accurate solution in a few iterations. The desired tolerance (e.g. 1.0e-4 = 1 part in 10000) and maximum # of iterations are specified as arguments. Setting the N argument will print statistics to the screen and log file about regarding the lengths of bonds and angles that are being constrained. Small delta values mean SHAKE is doing a good job. In LAMMPS, only small clusters of atoms can be constrained. This is so the constraint calculation for a cluster can be performed by a single processor, to enable good parallel performance. A cluster is defined as a central atom connected to others in the cluster by constrained bonds. LAMMPS allows for the following kinds of clusters to be constrained: one central atom bonded to 1 or 2 or 3 atoms, or one central atom bonded to 2 others and the angle between the 3 atoms also constrained. This means water molecules or CH2 or CH3 groups may be constrained, but not all the C-C backbone bonds of a long polymer chain. The {b} constraint lists bond types that will be constrained. The {t} constraint lists atom types. All bonds connected to an atom of the specified type will be constrained. The {m} constraint lists atom masses. All bonds connected to atoms of the specified masses will be constrained (within a fudge factor of MASSDELTA specified in fix_shake.cpp). The {a} constraint lists angle types. If both bonds in the angle are constrained then the angle will also be constrained if its type is in the list. For all constraints, a particular bond is only constrained if both atoms in the bond are in the group specified with the SHAKE fix. The degrees-of-freedom removed by SHAKE bonds and angles are accounted for in temperature and pressure computations. Similarly, the SHAKE contribution to the pressure of the system (virial) is also accounted for. NOTE: This command works by using the current forces on atoms to caculate an additional constraint force which when added will leave the atoms in positions that satisfy the SHAKE constraints (e.g. bond length) after the next time integration step. If you define fixes (e.g. "fix efield"_fix_efield.html) that add additional force to the atoms after fix shake operates, then this fix will not take them into account and the time integration will typically not satisfy the SHAKE constraints. The solution for this is to make sure that fix shake is defined in your input script after any other fixes which add or change forces (to atoms that fix shake operates on). :line The {mol} keyword should be used when other commands, such as "fix deposit"_fix_deposit.html or "fix pour"_fix_pour.html, add molecules on-the-fly during a simulation, and you wish to contrain the new molecules via SHAKE. You specify a {template-ID} previously defined using the "molecule"_molecule.html command, which reads a file that defines the molecule. You must use the same {template-ID} that the command adding molecules uses. The coordinates, atom types, special bond restrictions, and SHAKE info can be specified in the molecule file. See the "molecule"_molecule.html command for details. The only settings required to be in this file (by this command) are the SHAKE info of atoms in the molecule. :line Styles with a suffix are functionally the same as the corresponding style without the suffix. They have been optimized to run faster, depending on your available hardware, as discussed in "Section 5"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. These accelerated styles are part of the GPU, USER-INTEL, KOKKOS, USER-OMP and OPT packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. You can specify the accelerated styles explicitly in your input script by including their suffix, or you can use the "-suffix command-line switch"_Section_start.html#start_7 when you invoke LAMMPS, or you can use the "suffix"_suffix.html command in your input script. See "Section 5"_Section_accelerate.html of the manual for more instructions on how to use the accelerated styles effectively. :line [RATTLE:] The velocity constraints lead to a linear system of equations which can be solved analytically. The implementation of the algorithm in LAMMPS closely follows ("Andersen (1983)"_#Andersen). - + NOTE: The fix rattle command modifies forces and velocities and thus should be defined after all other integration fixes in your input script. If you define other fixes that modify velocities or forces after fix rattle operates, then fix rattle will not take them into account and the overall time integration will typically not satisfy the RATTLE constraints. You can check whether the constraints work correctly by setting the value of RATTLE_DEBUG in src/fix_rattle.cpp to 1 and recompiling LAMMPS. :line [Restart, fix_modify, output, run start/stop, minimize info:] No information about these fixes is written to "binary restart files"_restart.html. None of the "fix_modify"_fix_modify.html options are relevant to these fixes. No global or per-atom quantities are stored by these fixes for access by various "output commands"_Section_howto.html#howto_15. No parameter of these fixes can be used with the {start/stop} keywords of the "run"_run.html command. These fixes are not invoked during "energy minimization"_minimize.html. [Restrictions:] These fixes are part of the RIGID package. They are only enabled if LAMMPS was built with that package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. For computational efficiency, there can only be one shake or rattle fix defined in a simulation. If you use a tolerance that is too large or a max-iteration count that is too small, the constraints will not be enforced very strongly, which can lead to poor energy conservation. You can test for this in your system by running a constant NVE simulation with a particular set of SHAKE parameters and monitoring the energy versus time. SHAKE or RATTLE should not be used to contrain an angle at 180 degrees (e.g. linear CO2 molecule). This causes numeric difficulties. [Related commands:] none [Default:] none :line :link(Ryckaert) [(Ryckaert)] J.-P. Ryckaert, G. Ciccotti and H. J. C. Berendsen, J of Comp Phys, 23, 327-341 (1977). :link(Andersen) [(Andersen)] H. Andersen, J of Comp Phys, 52, 24-34 (1983). diff --git a/doc/src/fix_store_state.txt b/doc/src/fix_store_state.txt index 6521f078b..df694fb97 100644 --- a/doc/src/fix_store_state.txt +++ b/doc/src/fix_store_state.txt @@ -1,129 +1,129 @@ "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 fix store/state command :h3 [Syntax:] fix ID group-ID store/state N input1 input2 ... keyword value ... :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l store/state = style name of this fix command :l N = store atom attributes every N steps, N = 0 for initial store only :l input = one or more atom attributes :l possible attributes = id, mol, type, mass, - x, y, z, xs, ys, zs, xu, yu, zu, xsu, ysu, zsu, ix, iy, iz, - vx, vy, vz, fx, fy, fz, + x, y, z, xs, ys, zs, xu, yu, zu, xsu, ysu, zsu, ix, iy, iz, + vx, vy, vz, fx, fy, fz, q, mux, muy, muz, mu, radius, diameter, omegax, omegay, omegaz, angmomx, angmomy, angmomz, tqx, tqy, tqz, c_ID, c_ID\[N\], f_ID, f_ID\[N\], v_name, d_name, i_name :pre id = atom ID mol = molecule ID type = atom type mass = atom mass x,y,z = unscaled atom coordinates xs,ys,zs = scaled atom coordinates xu,yu,zu = unwrapped atom coordinates xsu,ysu,zsu = scaled unwrapped atom coordinates ix,iy,iz = box image that the atom is in vx,vy,vz = atom velocities fx,fy,fz = forces on atoms q = atom charge mux,muy,muz = orientation of dipolar atom mu = magnitued of dipole moment of atom radius,diameter = radius.diameter of spherical particle omegax,omegay,omegaz = angular velocity of spherical particle angmomx,angmomy,angmomz = angular momentum of aspherical particle tqx,tqy,tqz = torque on finite-size particles c_ID = per-atom vector calculated by a compute with ID c_ID\[I\] = Ith column of per-atom array calculated by a compute with ID f_ID = per-atom vector calculated by a fix with ID f_ID\[I\] = Ith column of per-atom array calculated by a fix with ID v_name = per-atom vector calculated by an atom-style variable with name d_name = per-atom floating point vector name, managed by fix property/atom i_name = per-atom integer vector name, managed by fix property/atom :pre zero or more keyword/value pairs may be appended :l keyword = {com} :l {com} value = {yes} or {no} :pre :ule [Examples:] fix 1 all store/state 0 x y z fix 1 all store/state 0 xu yu zu com yes fix 2 all store/state 1000 vx vy vz :pre [Description:] Define a fix that stores attributes for each atom in the group at the time the fix is defined. If {N} is 0, then the values are never updated, so this is a way of archiving an atom attribute at a given time for future use in a calculation or output. See the discussion of "output commands"_Section_howto.html#howto_15 that take fixes as inputs. If {N} is not zero, then the attributes will be updated every {N} steps. NOTE: Actually, only atom attributes specified by keywords like {xu} or {vy} or {radius} are initially stored immediately at the point in your input script when the fix is defined. Attributes specified by a compute, fix, or variable are not initially stored until the first run following the fix definition begins. This is because calculating those attributes may require quantities that are not defined in between runs. The list of possible attributes is the same as that used by the "dump custom"_dump.html command, which describes their meaning. If the {com} keyword is set to {yes} then the {xu}, {yu}, and {zu} inputs store the position of each atom relative to the center-of-mass of the group of atoms, instead of storing the absolute position. The requested values are stored in a per-atom vector or array as discussed below. Zeroes are stored for atoms not in the specified group. [Restart, fix_modify, output, run start/stop, minimize info:] This fix writes the per-atom values it stores to "binary restart files"_restart.html, so that the values can be restored when a simulation is restarted. See the "read_restart"_read_restart.html command for info on how to re-specify a fix in an input script that reads a restart file, so that the operation of the fix continues in an uninterrupted fashion. None of the "fix_modify"_fix_modify.html options are relevant to this fix. If a single input is specified, this fix produces a per-atom vector. If multiple inputs are specified, a per-atom array is produced where the number of columns for each atom is the number of inputs. These can be accessed by various "output commands"_Section_howto.html#howto_15. The per-atom values be accessed on any timestep. No parameter of this fix can be used with the {start/stop} keywords of the "run"_run.html command. This fix is not invoked during "energy minimization"_minimize.html. [Restrictions:] none [Related commands:] "dump custom"_dump.html, "compute property/atom"_compute_property_atom.html, "fix property/atom"_fix_property_atom.html, "variable"_variable.html [Default:] The option default is com = no. diff --git a/doc/src/fix_ti_spring.txt b/doc/src/fix_ti_spring.txt old mode 100755 new mode 100644 diff --git a/doc/src/fix_wall_gran.txt b/doc/src/fix_wall_gran.txt index d19f243ad..f30872186 100644 --- a/doc/src/fix_wall_gran.txt +++ b/doc/src/fix_wall_gran.txt @@ -1,168 +1,170 @@ "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 fix wall/gran command :h3 [Syntax:] fix ID group-ID wall/gran fstyle Kn Kt gamma_n gamma_t xmu dampflag wallstyle args keyword values ... :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l wall/gran = style name of this fix command :l fstyle = style of force interactions between particles and wall :l possible choices: hooke, hooke/history, hertz/history :pre Kn = elastic constant for normal particle repulsion (force/distance units or pressure units - see discussion below) :l Kt = elastic constant for tangential contact (force/distance units or pressure units - see discussion below) :l gamma_n = damping coefficient for collisions in normal direction (1/time units or 1/time-distance units - see discussion below) :l gamma_t = damping coefficient for collisions in tangential direction (1/time units or 1/time-distance units - see discussion below) :l xmu = static yield criterion (unitless value between 0.0 and 1.0e4) :l dampflag = 0 or 1 if tangential damping force is excluded or included :l wallstyle = {xplane} or {yplane} or {zplane} or {zcylinder} :l args = list of arguments for a particular style :l {xplane} or {yplane} or {zplane} args = lo hi lo,hi = position of lower and upper plane (distance units), either can be NULL) {zcylinder} args = radius radius = cylinder radius (distance units) :pre zero or more keyword/value pairs may be appended to args :l keyword = {wiggle} or {shear} :l {wiggle} values = dim amplitude period dim = {x} or {y} or {z} amplitude = size of oscillation (distance units) period = time of oscillation (time units) {shear} values = dim vshear dim = {x} or {y} or {z} vshear = magnitude of shear velocity (velocity units) :pre :ule [Examples:] fix 1 all wall/gran hooke 200000.0 NULL 50.0 NULL 0.5 0 xplane -10.0 10.0 fix 1 all wall/gran hooke/history 200000.0 NULL 50.0 NULL 0.5 0 zplane 0.0 NULL fix 2 all wall/gran hooke 100000.0 20000.0 50.0 30.0 0.5 1 zcylinder 15.0 wiggle z 3.0 2.0 :pre [Description:] Bound the simulation domain of a granular system with a frictional wall. All particles in the group interact with the wall when they are close enough to touch it. The nature of the wall/particle interactions are determined by the {fstyle} setting. It can be any of the styles defined by the "pair_style granular"_pair_gran.html commands. Currently this is {hooke}, {hooke/history}, or {hertz/history}. The equation for the force between the wall and particles touching it is the same as the corresponding equation on the "pair_style granular"_pair_gran.html doc page, in the limit of one of the two particles going to infinite radius and mass (flat wall). Specifically, delta = radius - r = overlap of particle with wall, m_eff = mass of particle, and the effective radius of contact = RiRj/Ri+Rj is just the radius of the particle. The parameters {Kn}, {Kt}, {gamma_n}, {gamma_t}, {xmu} and {dampflag} have the same meaning and units as those specified with the "pair_style granular"_pair_gran.html commands. This means a NULL can be used for either {Kt} or {gamma_t} as described on that page. If a NULL is used for {Kt}, then a default value is used where {Kt} = 2/7 {Kn}. If a NULL is used for {gamma_t}, then a default value is used where {gamma_t} = 1/2 {gamma_n}. Note that you can choose a different force styles and/or different values for the 6 wall/particle coefficients than for particle/particle interactions. E.g. if you wish to model the wall as a different material. NOTE: As discussed on the doc page for "pair_style granular"_pair_gran.html, versions of LAMMPS before 9Jan09 used a different equation for Hertzian interactions. This means Hertizian wall/particle interactions have also changed. They now include a sqrt(radius) term which was not present before. Also the previous versions used Kn and Kt from the pairwise interaction and hardwired dampflag to 1, rather than letting them be specified directly. This means you can set the values of the wall/particle coefficients appropriately in the current code to reproduce the results of a prevoius Hertzian monodisperse calculation. For example, for the common case of a monodisperse system with particles of diameter 1, Kn, Kt, gamma_n, and gamma_s should be set sqrt(2.0) larger than they were previously. The effective mass {m_eff} in the formulas listed on the "pair_style granular"_pair_gran.html doc page is the mass of the particle for particle/wall interactions (mass of wall is infinite). If the particle is part of a rigid body, its mass is replaced by the mass of the rigid body in those formulas. This is determined by searching for a "fix rigid"_fix_rigid.html command (or its variants). The {wallstyle} can be planar or cylindrical. The 3 planar options specify a pair of walls in a dimension. Wall positions are given by {lo} and {hi}. Either of the values can be specified as NULL if a single wall is desired. For a {zcylinder} wallstyle, the cylinder's axis is at x = y = 0.0, and the radius of the cylinder is specified. Optionally, the wall can be moving, if the {wiggle} or {shear} keywords are appended. Both keywords cannot be used together. For the {wiggle} keyword, the wall oscillates sinusoidally, similar to the oscillations of particles which can be specified by the "fix move"_fix_move.html command. This is useful in packing simulations of granular particles. The arguments to the {wiggle} keyword specify a dimension for the motion, as well as it's {amplitude} and {period}. Note that if the dimension is in the plane of the wall, this is effectively a shearing motion. If the dimension is perpendicular to the wall, it is more of a shaking motion. A {zcylinder} wall can only be wiggled in the z dimension. Each timestep, the position of a wiggled wall in the appropriate {dim} is set according to this equation: position = coord + A - A cos (omega * delta) :pre where {coord} is the specified initial position of the wall, {A} is the {amplitude}, {omega} is 2 PI / {period}, and {delta} is the time elapsed since the fix was specified. The velocity of the wall is set to the derivative of this expression. For the {shear} keyword, the wall moves continuously in the specified dimension with velocity {vshear}. The dimension must be tangential to walls with a planar {wallstyle}, e.g. in the {y} or {z} directions for an {xplane} wall. For {zcylinder} walls, a dimension of {z} means the cylinder is moving in the z-direction along it's axis. A dimension of {x} or {y} means the cylinder is spinning around the z-axis, either in the clockwise direction for {vshear} > 0 or counter-clockwise for {vshear} < 0. In this case, {vshear} is the tangential velocity of the wall at whatever {radius} has been defined. [Restart, fix_modify, output, run start/stop, minimize info:] This fix writes the shear friction state of atoms interacting with the wall to "binary restart files"_restart.html, so that a simulation can continue correctly if granular potentials with shear "history" effects are being used. See the "read_restart"_read_restart.html command for info on how to re-specify a fix in an input script that reads a restart file, so that the operation of the fix continues in an uninterrupted fashion. None of the "fix_modify"_fix_modify.html options are relevant to this fix. No global or per-atom quantities are stored by this fix for access by various "output commands"_Section_howto.html#howto_15. No parameter of this fix can be used with the {start/stop} keywords of the "run"_run.html command. This fix is not invoked during "energy minimization"_minimize.html. [Restrictions:] This fix is part of the GRANULAR 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. Any dimension (xyz) that has a granular wall must be non-periodic. [Related commands:] -"fix move"_fix_move.html, "pair_style granular"_pair_gran.html +"fix move"_fix_move.html, +"fix wall/gran/region"_fix_wall_gran_region.html, +"pair_style granular"_pair_gran.html [Default:] none diff --git a/doc/src/fix_wall_gran_region.txt b/doc/src/fix_wall_gran_region.txt new file mode 100644 index 000000000..63092486e --- /dev/null +++ b/doc/src/fix_wall_gran_region.txt @@ -0,0 +1,199 @@ +"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 + +fix wall/gran/region command :h3 + +[Syntax:] + +fix ID group-ID wall/gran/region fstyle Kn Kt gamma_n gamma_t xmu dampflag wallstyle regionID :pre + +ID, group-ID are documented in "fix"_fix.html command :ulb,l +wall/region = style name of this fix command :l +fstyle = style of force interactions between particles and wall :l + possible choices: hooke, hooke/history, hertz/history :pre +Kn = elastic constant for normal particle repulsion (force/distance units or pressure units - see discussion below) :l +Kt = elastic constant for tangential contact (force/distance units or pressure units - see discussion below) :l +gamma_n = damping coefficient for collisions in normal direction (1/time units or 1/time-distance units - see discussion below) :l +gamma_t = damping coefficient for collisions in tangential direction (1/time units or 1/time-distance units - see discussion below) :l +xmu = static yield criterion (unitless value between 0.0 and 1.0e4) :l +dampflag = 0 or 1 if tangential damping force is excluded or included :l +wallstyle = region (see "fix wall/gran"_fix_wall_gran.html for options for other kinds of walls) :l +region-ID = region whose boundary will act as wall :l,ule + +[Examples:] + +fix wall all wall/gran/region hooke/history 1000.0 200.0 200.0 100.0 0.5 1 region myCone :pre + +[Description:] + +Treat the surface of the geometric region defined by the {region-ID} +as a bounding frictional wall which interacts with nearby finite-size +granular particles when they are close enough to touch the wall. See +the "fix wall/region"_fix_wall_region.html and "fix +wall/gran"_fix_wall_gran.html commands for related kinds of walls for +non-granular particles and simpler wall geometries, respectively. + +Here are snapshots of example models using this command. +Corresponding input scripts can be found in examples/granregion. +Click on the images to see a bigger picture. Movies of these +simulations are "here on the Movies +page"_http://lammps.sandia.gov/movies.html#granregion of the +LAMMPS web site. + +:image(JPG/gran_funnel_small.jpg,JPG/gran_funnel.png) +:image(JPG/gran_mixer_small.jpg,JPG/gran_mixer.png) + +:line + +The distance between a particle and the region boundary is the +distance to the nearest point on the region surface. The force the +wall exerts on the particle is along the direction between that point +and the particle center, which is the direction normal to the surface +at that point. Note that if the region surface is comprised of +multiple "faces", then each face can exert a force on the particle if +it is close enough. E.g. for "region_style block"_region.html, a +particle in the interior, near a corner of the block, could feel wall +forces from 1, 2, or 3 faces of the block. + +Regions are defined using the "region"_region.html command. Note that +the region volume can be interior or exterior to the bounding surface, +which will determine in which direction the surface interacts with +particles, i.e. the direction of the surface normal. The exception to +this is if one or more {open} options are specified for the region +command, in which case particles interact with both the interior and +exterior surfaces of regions. + +Regions can either be primitive shapes (block, sphere, cylinder, etc) +or combinations of primitive shapes specified via the {union} or +{intersect} region styles. These latter styles can be used to +construct particle containers with complex shapes. Regions can also +move dynamically via the "region"_region.html command keywords (move) +and {rotate}, or change their shape by use of variables as inputs to +the "region"_region.html command. If such a region is used with this +fix, then the region surface will move in time in the corresponding +manner. + +NOTE: As discussed on the "region"_region.html command doc page, +regions in LAMMPS do not get wrapped across periodic boundaries. It +is up to you to ensure that the region location with respect to +periodic or non-periodic boundaries is specified appropriately via the +"region"_region.html and "boundary"_boundary.html commands when using +a region as a wall that bounds particle motion. + +NOTE: For primitive regions with sharp corners and/or edges (e.g. a +block or cylinder), wall/particle forces are computed accurately for +both interior and exterior regions. For {union} and {intersect} +regions, additional sharp corners and edges may be present due to the +intersection of the surfaces of 2 or more primitive volumes. These +corners and edges can be of two types: concave or convex. Concave +points/edges are like the corners of a cube as seen by particles in +the interior of a cube. Wall/particle forces around these features +are computed correctly. Convex points/edges are like the corners of a +cube as seen by particles exterior to the cube, i.e. the points jut +into the volume where particles are present. LAMMPS does NOT compute +the location of these convex points directly, and hence wall/particle +forces in the cutoff volume around these points suffer from +inaccuracies. The basic problem is that the outward normal of the +surface is not continuous at these points. This can cause particles +to feel no force (they don't "see" the wall) when in one location, +then move a distance epsilon, and suddenly feel a large force because +they now "see" the wall. In a worst-case scenario, this can blow +particles out of the simulation box. Thus, as a general rule you +should not use the fix wall/gran/region command with {union} or +{interesect} regions that have convex points or edges resulting from +the union/intersection (convex points/edges in the union/intersection +due to a single sub-region are still OK). + +NOTE: Similarly, you should not define {union} or {intersert} regions +for use with this command that share an overlapping common face that +is part of the overall outer boundary (interior boundary is OK), even +if the face is smooth. E.g. two regions of style block in a {union} +region, where the two blocks overlap on one or more of their faces. +This is because LAMMPS discards points that are part of multiple +sub-regions when calculating wall/particle interactions, to avoid +double-counting the interaction. Having two coincident faces could +cause the face to become invisible to the particles. The solution is +to make the two faces differ by epsilon in their position. + +The nature of the wall/particle interactions are determined by the +{fstyle} setting. It can be any of the styles defined by the +"pair_style granular"_pair_gran.html commands. Currently this is +{hooke}, {hooke/history}, or {hertz/history}. The equation for the +force between the wall and particles touching it is the same as the +corresponding equation on the "pair_style granular"_pair_gran.html doc +page, but the effective radius is calculated using the radius of the +particle and the radius of curvature of the wall at the contact point. + +Specifically, delta = radius - r = overlap of particle with wall, +m_eff = mass of particle, and RiRj/Ri+Rj is the effective radius, with +Rj replaced by the radius of curvature of the wall at the contact +point. The radius of curvature can be negative for a concave wall +section, e.g. the interior of cylinder. For a flat wall, delta = +radius - r = overlap of particle with wall, m_eff = mass of particle, +and the effective radius of contact is just the radius of the +particle. + +The parameters {Kn}, {Kt}, {gamma_n}, {gamma_t}, {xmu} and {dampflag} +have the same meaning and units as those specified with the +"pair_style granular"_pair_gran.html commands. This means a NULL can +be used for either {Kt} or {gamma_t} as described on that page. If a +NULL is used for {Kt}, then a default value is used where {Kt} = 2/7 +{Kn}. If a NULL is used for {gamma_t}, then a default value is used +where {gamma_t} = 1/2 {gamma_n}. + +Note that you can choose a different force styles and/or different +values for the 6 wall/particle coefficients than for particle/particle +interactions. E.g. if you wish to model the wall as a different +material. + +[Restart, fix_modify, output, run start/stop, minimize info:] + +Similiar to "fix wall/gran"_fix_wall_gran.html command, this fix +writes the shear friction state of atoms interacting with the wall to +"binary restart files"_restart.html, so that a simulation can continue +correctly if granular potentials with shear "history" effects are +being used. This fix also includes info about a moving region in the +restart file. See the "read_restart"_read_restart.html command for +info on how to re-specify a fix in an input script that reads a +restart file, so that the operation of the fix continues in an +uninterrupted fashion. + +Note that info about region definitions is NOT included in restart +files. So you must re-define your region and if it is a moving +region, define its motion attributes in a way that is consistent with +the simulation that wrote the restart file. In particular, if you +want to change its motion attributes (e.g. its velocity), then you +should insure the postition/orientation of the region at the initial +restart timestep is the same as it was on the timestep the restart +file was written. If this is not possible, then you may need to +ignore info in the restart file by defining a new fix wall/gran/region +command in your restart script (e.g. with a different fix ID). + +None of the "fix_modify"_fix_modify.html options are relevant to this +fix. No global or per-atom quantities are stored by this fix for +access by various "output commands"_Section_howto.html#howto_15. No +parameter of this fix can be used with the {start/stop} keywords of +the "run"_run.html command. This fix is not invoked during "energy +minimization"_minimize.html. + +[Restrictions:] + +This fix is part of the GRANULAR 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. + +[Related commands:] + +"fix_move"_fix_move.html, +"fix wall/gran"_fix_wall_gran.html, +"fix wall/region"_fix_wall_region.html, +"pair_style granular"_pair_gran.html, +"region"_region.html + +[Default:] none + diff --git a/doc/src/group.txt b/doc/src/group.txt index a72efebb8..ab975af75 100644 --- a/doc/src/group.txt +++ b/doc/src/group.txt @@ -1,284 +1,284 @@ "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 group command :h3 [Syntax:] group ID style args :pre ID = user-defined name of the group :ulb,l style = {delete} or {region} or {type} or {id} or {molecule} or {variable} or \ {include} or {subtract} or {union} or {intersect} or \ {dynamic} or {static} :l {delete} = no args {clear} = no args {region} args = region-ID {type} or {id} or {molecule} args = list of one or more atom types, atom IDs, or molecule IDs any entry in list can be a sequence formatted as A:B or A:B:C where A = starting index, B = ending index, C = increment between indices, 1 if not specified args = logical value logical = "<" or "<=" or ">" or ">=" or "==" or "!=" value = an atom type or atom ID or molecule ID (depending on {style}) args = logical value1 value2 logical = "<>" value1,value2 = atom types or atom IDs or molecule IDs (depending on {style}) {variable} args = variable-name {include} args = molecule molecule = add atoms to group with same molecule ID as atoms already in group {subtract} args = two or more group IDs {union} args = one or more group IDs {intersect} args = two or more group IDs {dynamic} args = parent-ID keyword value ... one or more keyword/value pairs may be appended keyword = {region} or {var} or {every} {region} value = region-ID {var} value = name of variable {every} value = N = update group every this many timesteps {static} = no args :pre :ule [Examples:] group edge region regstrip group water type 3 4 group sub id 10 25 50 group sub id 10 25 50 500:1000 group sub id 100:10000:10 group sub id <= 150 group polyA molecule <> 50 250 group hienergy variable eng group hienergy include molecule group boundary subtract all a2 a3 group boundary union lower upper group boundary intersect upper flow group boundary delete group mine dynamic all region myRegion every 100 :pre [Description:] Identify a collection of atoms as belonging to a group. The group ID can then be used in other commands such as "fix"_fix.html, "compute"_compute.html, "dump"_dump.html, or "velocity"_velocity.html to act on those atoms together. If the group ID already exists, the group command adds the specified atoms to the group. NOTE: By default groups are static, meaning the atoms are permanently assigned to the group. For example, if the {region} style is used to assign atoms to a group, the atoms will remain in the group even if they later move out of the region. As explained below, the {dynamic} style can be used to make a group dynamic so that a periodic determination is made as to which atoms are in the group. Since many LAMMPS commands operate on groups of atoms, you should think carefully about whether making a group dynamic makes sense for your model. A group with the ID {all} is predefined. All atoms belong to this group. This group cannot be deleted, or made dynamic. The {delete} style removes the named group and un-assigns all atoms that were assigned to that group. Since there is a restriction (see below) that no more than 32 groups can be defined at any time, the {delete} style allows you to remove groups that are no longer needed, so that more can be specified. You cannot delete a group if it has been used to define a current "fix"_fix.html or "compute"_compute.html or "dump"_dump.html. The {clear} style un-assigns all atoms that were assigned to that group. This may be dangerous to do during a simulation run, e.g. using the "run every"_run.html command if a fix or compute or other operation expects the atoms in the group to remain constant, but LAMMPS does not check for this. The {region} style puts all atoms in the region volume into the group. Note that this is a static one-time assignment. The atoms remain assigned (or not assigned) to the group even in they later move out of the region volume. The {type}, {id}, and {molecule} styles put all atoms with the specified atom types, atom IDs, or molecule IDs into the group. These 3 styles can use arguments specified in one of two formats. The first format is a list of values (types or IDs). For example, the 2nd command in the examples above puts all atoms of type 3 or 4 into the group named {water}. Each entry in the list can be a colon-separated sequence A:B or A:B:C, as in two of the examples above. A "sequence" generates a sequence of values (types or IDs), with an optional increment. The first example with 500:1000 has the default increment of 1 and would add all atom IDs from 500 to 1000 (inclusive) to the group sub, along with 10,25,50 since they also appear in the list of values. The second example with 100:10000:10 uses an increment of 10 and would thus would add atoms IDs 100,110,120, ... 9990,10000 to the group sub. The second format is a {logical} followed by one or two values (type or ID). The 7 valid logicals are listed above. All the logicals except <> take a single argument. The 3rd example above adds all atoms with IDs from 1 to 150 to the group named {sub}. The logical <> means "between" and takes 2 arguments. The 4th example above adds all atoms belonging to molecules with IDs from 50 to 250 (inclusive) to the group named polyA. The {variable} style evaluates a variable to determine which atoms to add to the group. It must be an "atom-style variable"_variable.html previously defined in the input script. If the variable evaluates to a non-zero value for a particular atom, then that atom is added to the specified group. Atom-style variables can specify formulas that include thermodynamic quantities, per-atom values such as atom coordinates, or per-atom quantities calculated by computes, fixes, or other variables. They can also include Boolean logic where 2 numeric values are compared to yield a 1 or 0 (effectively a true or false). Thus using the {variable} style, is a general way to flag specific atoms to include or exclude from a group. For example, these lines define a variable "eatom" that calculates the potential energy of each atom and includes it in the group if its potential energy is above the threshhold value -3.0. compute 1 all pe/atom compute 2 all reduce sum c_1 thermo_style custom step temp pe c_2 run 0 :pre variable eatom atom "c_1 > -3.0" group hienergy variable eatom :pre Note that these lines compute 2 all reduce sum c_1 thermo_style custom step temp pe c_2 run 0 :pre are necessary to insure that the "eatom" variable is current when the group command invokes it. Because the eatom variable computes the per-atom energy via the pe/atom compute, it will only be current if a run has been performed which evaluated pairwise energies, and the pe/atom compute was actually invoked during the run. Printing the thermodyanmic info for compute 2 insures that this is the case, since it sums the pe/atom compute values (in the reduce compute) to output them to the screen. See the "Variable Accuracy" section of the "variable"_variable.html doc page for more details on insuring that variables are current when they are evaluated between runs. The {include} style with its arg {molecule} adds atoms to a group that have the same molecule ID as atoms already in the group. The molecule ID = 0 is ignored in this operation, since it is assumed to flag isolated atoms that are not part of molecules. An example of where this operation is useful is if the {region} style has been used previously to add atoms to a group that are within a geometric region. If molecules straddle the region boundary, then atoms outside the region that are part of molecules with atoms inside the region will not be in the group. Using the group command a 2nd time with {include molecule} will add those atoms that are outside the region to the group. NOTE: The {include molecule} operation is relatively expensive in a parallel sense. This is because it requires communication of relevant molecule IDs between all the processors and each processor to loop over its atoms once per processor, to compare its atoms to the list of molecule IDs from every other processor. Hence it scales as N, rather than N/P as most of the group operations do, where N is the number of atoms, and P is the number of processors. The {subtract} style takes a list of two or more existing group names as arguments. All atoms that belong to the 1st group, but not to any of the other groups are added to the specified group. The {union} style takes a list of one or more existing group names as arguments. All atoms that belong to any of the listed groups are added to the specified group. The {intersect} style takes a list of two or more existing group names as arguments. Atoms that belong to every one of the listed groups are added to the specified group. :line The {dynamic} style flags an existing or new group as dynamic. This means atoms will be (re)assigned to the group periodically as a simulation runs. This is in contrast to static groups where atoms are permanently assigned to the group. The way the assignment occurs is as follows. Only atoms in the group specified as the parent group via the parent-ID are assigned to the dynamic group before the following conditions are applied. If the {region} keyword is used, atoms not in the specified region are removed from the dynamic group. If the {var} keyword is used, the variable name must be an atom-style or atomfile-style variable. The variable is evaluated and atoms whose per-atom values are 0.0, are removed from the dynamic group. The assignment of atoms to a dynamic group is done at the beginning of each run and on every timestep that is a multiple of {N}, which is the argument for the {every} keyword (N = 1 is the default). For an energy minimization, via the "minimize"_minimize.html command, an assignment is made at the beginning of the minimization, but not during the iterations of the minimizer. The point in the timestep at which atoms are assigned to a dynamic group is after the initial stage of velocity Verlet time integration has been performed, and before neighbor lists or forces are computed. This is the point in the timestep where atom positions have just changed due to the time integration, so the region criterion should be accurate, if applied. NOTE: If the {region} keyword is used to determine what atoms are in the dynamic group, atoms can move outside of the simulation box between reneighboring events. Thus if you want to include all atoms on the left side of the simulation box, you probably want to set the left boundary of the region to be outside the simulation box by some reasonable amount (e.g. up to the cutoff of the potential), else they may be excluded from the dynamic region. Here is an example of using a dynamic group to shrink the set of atoms being integrated by using a spherical region with a variable radius (shrinking from 18 to 5 over the course of the run). This could be used to model a quench of the system, freezing atoms outside the shrinking sphere, then converting the remaining atoms to a static group and running further. variable nsteps equal 5000 variable rad equal 18-(step/v_nsteps)*(18-5) region ss sphere 20 20 0 v_rad group mobile dynamic all region ss fix 1 mobile nve run $\{nsteps\} group mobile static -run $\{nsteps\} :pre +run $\{nsteps\} :pre NOTE: All fixes and computes take a group ID as an argument, but they do not all allow for use of a dynamic group. If you get an error message that this is not allowed, but feel that it should be for the fix or compute in question, then please post your reasoning to the LAMMPS mail list and we can change it. The {static} style removes the setting for a dynamic group, converting it to a static group (the default). The atoms in the static group are those currently in the dynamic group. :line [Restrictions:] There can be no more than 32 groups defined at one time, including "all". The parent group of a dynamic group cannot itself be a dynamic group. [Related commands:] "dump"_dump.html, "fix"_fix.html, "region"_region.html, "velocity"_velocity.html [Default:] All atoms belong to the "all" group. diff --git a/doc/src/if.txt b/doc/src/if.txt index c3eb98f22..aa93c7379 100644 --- a/doc/src/if.txt +++ b/doc/src/if.txt @@ -1,192 +1,192 @@ "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 if command :h3 [Syntax:] if boolean then t1 t2 ... elif boolean f1 f2 ... elif boolean f1 f2 ... else e1 e2 ... :pre boolean = a Boolean expression evaluated as TRUE or FALSE (see below) then = required word t1,t2,...,tN = one or more LAMMPS commands to execute if condition is met, each enclosed in quotes elif = optional word, can appear multiple times f1,f2,...,fN = one or more LAMMPS commands to execute if elif condition is met, each enclosed in quotes (optional arguments) else = optional argument e1,e2,...,eN = one or more LAMMPS commands to execute if no condition is met, each enclosed in quotes (optional arguments) :ul [Examples:] if "$\{steps\} > 1000" then quit if "$\{myString\} == a10" then quit if "$x <= $y" then "print X is smaller = $x" else "print Y is smaller = $y" if "($\{eng\} > 0.0) || ($n < 1000)" then & "timestep 0.005" & elif $n<10000 & "timestep 0.01" & else & "timestep 0.02" & "print 'Max step reached'" if "$\{eng\} > $\{eng_previous\}" then "jump file1" else "jump file2" :pre [Description:] This command provides an if-then-else capability within an input script. A Boolean expression is evaluted and the result is TRUE or FALSE. Note that as in the examples above, the expression can contain variables, as defined by the "variable"_variable.html command, which will be evaluated as part of the expression. Thus a user-defined formula that reflects the current state of the simulation can be used to issue one or more new commands. If the result of the Boolean expression is TRUE, then one or more commands (t1, t2, ..., tN) are executed. If it is FALSE, then Boolean expressions associated with successive elif keywords are evaluated until one is found to be true, in which case its commands (f1, f2, ..., fN) are executed. If no Boolean expression is TRUE, then the commands associated with the else keyword, namely (e1, e2, ..., eN), are executed. The elif and else keywords and their associated commands are optional. If they aren't specified and the initial Boolean expression is FALSE, then no commands are executed. The syntax for Boolean expressions is described below. Each command (t1, f1, e1, etc) can be any valid LAMMPS input script command, except an "include"_include.html command, which is not allowed. If the command is more than one word, it must enclosed in quotes, so it will be treated as a single argument, as in the examples above. NOTE: If a command itself requires a quoted argument (e.g. a "print"_print.html command), then double and single quotes can be used and nested in the usual manner, as in the examples above and below. See "Section 3.2"_Section_commands.html#cmd_2 of the manual for more details on using quotes in arguments. Only one of level of nesting is allowed, but that should be sufficient for most use cases. Note that by using the line continuation character "&", the if command can be spread across many lines, though it is still a single command: if "$a < $b" then & "print 'Minimum value = $a'" & "run 1000" & else & 'print "Minimum value = $b"' & "minimize 0.001 0.001 1000 10000" :pre Note that if one of the commands to execute is "quit"_quit.html, as in the first example above, then executing the command will cause LAMMPS to halt. Note that by jumping to a label in the same input script, the if command can be used to break out of a loop. See the "variable delete"_variable.html command for info on how to delete the associated loop variable, so that it can be re-used later in the input script. Here is an example of a loop which checks every 1000 steps if the system temperature has reached a certain value, and if so, breaks out of the loop to finish the run. Note that any variable could be checked, so long as it is current on the timestep when the run completes. As explained on the "variable"_variable.html doc page, this can be insured by includig the variable in thermodynamic output. variable myTemp equal temp label loop variable a loop 1000 run 1000 if "$\{myTemp\} < 300.0" then "jump SELF break" next a jump SELF loop label break print "ALL DONE" :pre Here is an example of a double loop which uses the if and "jump"_jump.html commands to break out of the inner loop when a condition is met, then continues iterating thru the outer loop. -label loopa +label loopa variable a loop 5 - label loopb + label loopb variable b loop 5 - print "A,B = $a,$b" + print "A,B = $a,$b" run 10000 - if "$b > 2" then "jump SELF break" - next b - jump in.script loopb -label break + if "$b > 2" then "jump SELF break" + next b + jump in.script loopb +label break variable b delete -next a -jump SELF loopa :pre +next a +jump SELF loopa :pre :line The Boolean expressions for the if and elif keywords have a C-like syntax. Note that each expression is a single argument within the if command. Thus if you want to include spaces in the expression for clarity, you must enclose the entire expression in quotes. An expression is built out of numbers (which start with a digit or period or minus sign) or strings (which start with a letter and can contain alphanumeric characters or underscores): 0.2, 100, 1.0e20, -15.4, etc InP, myString, a123, ab_23_cd, etc :pre and Boolean operators: A == B, A != B, A < B, A <= B, A > B, A >= B, A && B, A || B, A |^ B, !A :pre Each A and B is a number or string or a variable reference like $a or $\{abc\}, or A or B can be another Boolean expression. If a variable is used it can produce a number when evaluated, like an "equal-style variable"_variable.html. Or it can produce a string, like an "index-style variable"_variable.html. For an individual Boolean operator, A and B must both be numbers or must both be strings. You cannot compare a number to a string. Expressions are evaluated left to right and have the usual C-style precedence: the unary logical NOT operator "!" has the highest precedence, the 4 relational operators "<", "<=", ">", and ">=" are next; the two remaining relational operators "==" and "!=" are next; then the logical AND operator "&&"; and finally the logical OR operator "||" and logical XOR (exclusive or) operator "|^" have the lowest precedence. Parenthesis can be used to group one or more portions of an expression and/or enforce a different order of evaluation than what would occur with the default precedence. When the 6 relational operators (first 6 in list above) compare 2 numbers, they return either a 1.0 or 0.0 depending on whether the relationship between A and B is TRUE or FALSE. When the 6 relational operators compare 2 strings, they also return a 1.0 or 0.0 for TRUE or FALSE, but the comparison is done by the C function strcmp(). When the 3 logical operators (last 3 in list above) compare 2 numbers, they also return either a 1.0 or 0.0 depending on whether the relationship between A and B is TRUE or FALSE (or just A). The logical AND operator will return 1.0 if both its arguments are non-zero, else it returns 0.0. The logical OR operator will return 1.0 if either of its arguments is non-zero, else it returns 0.0. The logical XOR operator will return 1.0 if one of its arguments is zero and the other non-zero, else it returns 0.0. The logical NOT operator returns 1.0 if its argument is 0.0, else it returns 0.0. The 3 logical operators can only be used to operate on numbers, not on strings. The overall Boolean expression produces a TRUE result if the result is non-zero. If the result is zero, the expression result is FALSE. :line [Restrictions:] none [Related commands:] "variable"_variable.html, "print"_print.html [Default:] none diff --git a/doc/src/jump.txt b/doc/src/jump.txt index 1689071bc..e746ea782 100644 --- a/doc/src/jump.txt +++ b/doc/src/jump.txt @@ -1,130 +1,130 @@ "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 jump command :h3 [Syntax:] jump file label :pre file = filename of new input script to switch to label = optional label within file to jump to :ul [Examples:] jump newfile jump in.run2 runloop jump SELF runloop :pre [Description:] This command closes the current input script file, opens the file with the specified name, and begins reading LAMMPS commands from that file. Unlike the "include"_include.html command, the original file is not returned to, although by using multiple jump commands it is possible to chain from file to file or back to the original file. If the word "SELF" is used for the filename, then the current input script is re-opened and read again. NOTE: The SELF option is not guaranteed to work when the current input script is being read through stdin (standard input), e.g. lmp_g++ < in.script :pre since the SELF option invokes the C-library rewind() call, which may not be supported for stdin on some systems or by some MPI implementations. This can be worked around by using the "-in command-line argument"_Section_start.html#start_7, e.g. lmp_g++ -in in.script :pre or by using the "-var command-line argument"_Section_start.html#start_7 to pass the script name as a variable to the input script. In the latter case, a "variable"_variable.html called "fname" could be used in place of SELF, e.g. lmp_g++ -var fname in.script < in.script :pre The 2nd argument to the jump command is optional. If specified, it is treated as a label and the new file is scanned (without executing commands) until the label is found, and commands are executed from that point forward. This can be used to loop over a portion of the input script, as in this example. These commands perform 10 runs, each of 10000 steps, and create 10 dump files named file.1, file.2, etc. The "next"_next.html command is used to exit the loop after 10 iterations. When the "a" variable has been incremented for the tenth time, it will cause the next jump command to be skipped. variable a loop 10 label loop dump 1 all atom 100 file.$a run 10000 undump 1 next a jump in.lj loop :pre If the jump {file} argument is a variable, the jump command can be used to cause different processor partitions to run different input scripts. In this example, LAMMPS is run on 40 processors, with 4 partitions of 10 procs each. An in.file containing the example variable and jump command will cause each partition to run a different simulation. mpirun -np 40 lmp_ibm -partition 4x10 -in in.file :pre variable f world script.1 script.2 script.3 script.4 jump $f :pre Here is an example of a loop which checks every 1000 steps if the system temperature has reached a certain value, and if so, breaks out of the loop to finish the run. Note that any variable could be checked, so long as it is current on the timestep when the run completes. As explained on the "variable"_variable.html doc page, this can be insured by includig the variable in thermodynamic output. variable myTemp equal temp label loop variable a loop 1000 run 1000 if "$\{myTemp\} < 300.0" then "jump SELF break" next a jump SELF loop label break print "ALL DONE" :pre Here is an example of a double loop which uses the if and "jump"_jump.html commands to break out of the inner loop when a condition is met, then continues iterating thru the outer loop. -label loopa +label loopa variable a loop 5 - label loopb + label loopb variable b loop 5 - print "A,B = $a,$b" + print "A,B = $a,$b" run 10000 - if "$b > 2" then "jump SELF break" - next b - jump in.script loopb -label break + if "$b > 2" then "jump SELF break" + next b + jump in.script loopb +label break variable b delete -next a -jump SELF loopa :pre +next a +jump SELF loopa :pre [Restrictions:] If you jump to a file and it does not contain the specified label, LAMMPS will come to the end of the file and exit. [Related commands:] "variable"_variable.html, "include"_include.html, "label"_label.html, "next"_next.html [Default:] none diff --git a/doc/src/min_style.txt b/doc/src/min_style.txt old mode 100755 new mode 100644 diff --git a/doc/src/next.txt b/doc/src/next.txt index 2802350c5..69bffe8bb 100644 --- a/doc/src/next.txt +++ b/doc/src/next.txt @@ -1,142 +1,142 @@ "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 next command :h3 [Syntax:] next variables :pre variables = one or more variable names :ul [Examples:] next x next a t x myTemp :pre [Description:] This command is used with variables defined by the "variable"_variable.html command. It assigns the next value to the variable from the list of values defined for that variable by the "variable"_variable.html command. Thus when that variable is subsequently substituted for in an input script command, the new value is used. See the "variable"_variable.html command for info on how to define and use different kinds of variables in LAMMPS input scripts. If a variable name is a single lower-case character from "a" to "z", it can be used in an input script command as $a or $z. If it is multiple letters, it can be used as $\{myTemp\}. If multiple variables are used as arguments to the {next} command, then all must be of the same variable style: {index}, {loop}, {file}, {universe}, or {uloop}. An exception is that {universe}- and {uloop}-style variables can be mixed in the same {next} command. All the variables specified with the next command are incremented by one value from their respective list of values. A {file}-style variable reads the next line from its associated file. An {atomfile}-style variable reads the next set of lines (one per atom) from its associated file. {String-} or {atom}- or {equal}- or {world}-style variables cannot be used with the the next command, since they only store a single value. When any of the variables in the next command has no more values, a flag is set that causes the input script to skip the next "jump"_jump.html command encountered. This enables a loop containing a next command to exit. As explained in the "variable"_variable.html command, the variable that has exhausted its values is also deleted. This allows it to be used and re-defined later in the input script. {File}-style and {atomfile}-style variables are exhausted when the end-of-file is reached. When the next command is used with {index}- or {loop}-style variables, the next value is assigned to the variable for all processors. When the next command is used with {file}-style variables, the next line is read from its file and the string assigned to the variable. When the next command is used with {atomfile}-style variables, the next set of per-atom values is read from its file and assigned to the variable. When the next command is used with {universe}- or {uloop}-style variables, all {universe}- or {uloop}-style variables must be listed in the next command. This is because of the manner in which the incrementing is done, using a single lock file for all variables. The next value (for each variable) is assigned to whichever processor partition executes the command first. All processors in the partition are assigned the same value(s). Running LAMMPS on multiple partitions of processors via the "-partition" command-line switch is described in "this section"_Section_start.html#start_7 of the manual. {Universe}- and {uloop}-style variables are incremented using the files "tmp.lammps.variable" and "tmp.lammps.variable.lock" which you will see in your directory during and after such a LAMMPS run. Here is an example of running a series of simulations using the next command with an {index}-style variable. If this input script is named in.polymer, 8 simulations would be run using data files from directories run1 thru run8. variable d index run1 run2 run3 run4 run5 run6 run7 run8 shell cd $d read_data data.polymer run 10000 shell cd .. clear next d jump in.polymer :pre If the variable "d" were of style {universe}, and the same in.polymer input script were run on 3 partitions of processors, then the first 3 simulations would begin, one on each set of processors. Whichever partition finished first, it would assign variable "d" the 4th value and run another simulation, and so forth until all 8 simulations were finished. Jump and next commands can also be nested to enable multi-level loops. For example, this script will run 15 simulations in a double loop. variable i loop 3 variable j loop 5 clear ... read_data data.polymer.$i$j print Running simulation $i.$j run 10000 next j jump in.script next i jump in.script :pre Here is an example of a double loop which uses the "if"_if.html and "jump"_jump.html commands to break out of the inner loop when a condition is met, then continues iterating thru the outer loop. -label loopa +label loopa variable a loop 5 - label loopb + label loopb variable b loop 5 - print "A,B = $a,$b" + print "A,B = $a,$b" run 10000 - if $b > 2 then "jump in.script break" - next b - jump in.script loopb -label break + if $b > 2 then "jump in.script break" + next b + jump in.script loopb +label break variable b delete :pre -next a -jump in.script loopa :pre +next a +jump in.script loopa :pre [Restrictions:] As described above. [Related commands:] "jump"_jump.html, "include"_include.html, "shell"_shell.html, "variable"_variable.html, [Default:] none diff --git a/doc/src/pair_dipole.txt b/doc/src/pair_dipole.txt old mode 100755 new mode 100644 diff --git a/doc/src/pair_gayberne.txt b/doc/src/pair_gayberne.txt old mode 100755 new mode 100644 diff --git a/doc/src/pair_hybrid.txt b/doc/src/pair_hybrid.txt index dd72ab6eb..47451cf14 100644 --- a/doc/src/pair_hybrid.txt +++ b/doc/src/pair_hybrid.txt @@ -1,382 +1,382 @@ "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 pair_style hybrid command :h3 pair_style hybrid/omp command :h3 pair_style hybrid/overlay command :h3 pair_style hybrid/overlay/omp command :h3 [Syntax:] pair_style hybrid style1 args style2 args ... pair_style hybrid/overlay style1 args style2 args ... :pre style1,style2 = list of one or more pair styles and their arguments :ul [Examples:] pair_style hybrid lj/cut/coul/cut 10.0 eam lj/cut 5.0 pair_coeff 1*2 1*2 eam niu3 pair_coeff 3 3 lj/cut/coul/cut 1.0 1.0 pair_coeff 1*2 3 lj/cut 0.5 1.2 :pre pair_style hybrid/overlay lj/cut 2.5 coul/long 2.0 pair_coeff * * lj/cut 1.0 1.0 pair_coeff * * coul/long :pre [Description:] The {hybrid} and {hybrid/overlay} styles enable the use of multiple pair styles in one simulation. With the {hybrid} style, exactly one pair style is assigned to each pair of atom types. With the {hybrid/overlay} style, one or more pair styles can be assigned to each pair of atom types. The assignment of pair styles to type pairs is made via the "pair_coeff"_pair_coeff.html command. Here are two examples of hybrid simulations. The {hybrid} style could be used for a simulation of a metal droplet on a LJ surface. The metal atoms interact with each other via an {eam} potential, the surface atoms interact with each other via a {lj/cut} potential, and the metal/surface interaction is also computed via a {lj/cut} potential. The {hybrid/overlay} style could be used as in the 2nd example above, where multiple potentials are superposed in an additive fashion to compute the interaction between atoms. In this example, using {lj/cut} and {coul/long} together gives the same result as if the {lj/cut/coul/long} potential were used by itself. In this case, it would be more efficient to use the single combined potential, but in general any combination of pair potentials can be used together in to produce an interaction that is not encoded in any single pair_style file, e.g. adding Coulombic forces between granular particles. All pair styles that will be used are listed as "sub-styles" following the {hybrid} or {hybrid/overlay} keyword, in any order. Each sub-style's name is followed by its usual arguments, as illustrated in the example above. See the doc pages of individual pair styles for a listing and explanation of the appropriate arguments. Note that an individual pair style can be used multiple times as a sub-style. For efficiency this should only be done if your model requires it. E.g. if you have different regions of Si and C atoms and wish to use a Tersoff potential for pure Si for one set of atoms, and a Tersoff potetnial for pure C for the other set (presumably with some 3rd potential for Si-C interactions), then the sub-style {tersoff} could be listed twice. But if you just want to use a Lennard-Jones or other pairwise potential for several different atom type pairs in your model, then you should just list the sub-style once and use the pair_coeff command to assign parameters for the different type pairs. NOTE: There are two exceptions to this option to list an individual pair style multiple times. The first is for pair styles implemented as Fortran libraries: "pair_style meam"_pair_meam.html and "pair_style reax"_pair_reax.html ("pair_style reax/c"_pair_reax_c.html is OK). This is because unlike a C++ class, they can not be instantiated multiple times, due to the manner in which they were coded in Fortran. The second is for GPU-enabled pair styles in the GPU package. This is b/c the GPU package also currently assumes that only one instance of a pair style is being used. In the pair_coeff commands, the name of a pair style must be added after the I,J type specification, with the remaining coefficients being those appropriate to that style. If the pair style is used multiple times in the pair_style command, then an additional numeric argument must also be specified which is a number from 1 to M where M is the number of times the sub-style was listed in the pair style command. The extra number indicates which instance of the sub-style these coefficients apply to. For example, consider a simulation with 3 atom types: types 1 and 2 are Ni atoms, type 3 are LJ atoms with charges. The following commands would set up a hybrid simulation: pair_style hybrid eam/alloy lj/cut/coul/cut 10.0 lj/cut 8.0 pair_coeff * * eam/alloy nialhjea Ni Ni NULL pair_coeff 3 3 lj/cut/coul/cut 1.0 1.0 pair_coeff 1*2 3 lj/cut 0.8 1.3 :pre As an example of using the same pair style multiple times, consider a simulation with 2 atom types. Type 1 is Si, type 2 is C. The following commands would model the Si atoms with Tersoff, the C atoms with Tersoff, and the cross-interactions with Lennard-Jones: pair_style hybrid lj/cut 2.5 tersoff tersoff pair_coeff * * tersoff 1 Si.tersoff Si NULL pair_coeff * * tersoff 2 C.tersoff NULL C pair_coeff 1 2 lj/cut 1.0 1.5 :pre If pair coefficients are specified in the data file read via the "read_data"_read_data.html command, then the same rule applies. E.g. "eam/alloy" or "lj/cut" must be added after the atom type, for each line in the "Pair Coeffs" section, e.g. Pair Coeffs :pre 1 lj/cut/coul/cut 1.0 1.0 ... :pre Note that the pair_coeff command for some potentials such as "pair_style eam/alloy"_pair_eam.html includes a mapping specification of elements to all atom types, which in the hybrid case, can include atom types not assigned to the {eam/alloy} potential. The NULL keyword is used by many such potentials (eam/alloy, Tersoff, AIREBO, etc), to denote an atom type that will be assigned to a different sub-style. For the {hybrid} style, each atom type pair I,J is assigned to exactly one sub-style. Just as with a simulation using a single pair style, if you specify the same atom type pair in a second pair_coeff command, the previous assignment will be overwritten. For the {hybrid/overlay} style, each atom type pair I,J can be assigned to one or more sub-styles. If you specify the same atom type pair in a second pair_coeff command with a new sub-style, then the second sub-style is added to the list of potentials that will be calculated for two interacting atoms of those types. If you specify the same atom type pair in a second pair_coeff command with a sub-style that has already been defined for that pair of atoms, then the new pair coefficients simply override the previous ones, as in the normal usage of the pair_coeff command. E.g. these two sets of commands are the same: pair_style lj/cut 2.5 pair_coeff * * 1.0 1.0 pair_coeff 2 2 1.5 0.8 :pre pair_style hybrid/overlay lj/cut 2.5 pair_coeff * * lj/cut 1.0 1.0 pair_coeff 2 2 lj/cut 1.5 0.8 :pre Coefficients must be defined for each pair of atoms types via the "pair_coeff"_pair_coeff.html command as described above, or in the data file or restart files read by the "read_data"_read_data.html or "read_restart"_read_restart.html commands, or by mixing as described below. For both the {hybrid} and {hybrid/overlay} styles, every atom type pair I,J (where I <= J) must be assigned to at least one sub-style via the "pair_coeff"_pair_coeff.html command as in the examples above, or in the data file read by the "read_data"_read_data.html, or by mixing as described below. If you want there to be no interactions between a particular pair of atom types, you have 3 choices. You can assign the type pair to some sub-style and use the "neigh_modify exclude type"_neigh_modify.html command. You can assign it to some sub-style and set the coefficients so that there is effectively no interaction (e.g. epsilon = 0.0 in a LJ potential). Or, for {hybrid} and {hybrid/overlay} simulations, you can use this form of the pair_coeff command in your input script: -pair_coeff 2 3 none :pre +pair_coeff 2 3 none :pre or this form in the "Pair Coeffs" section of the data file: 3 none :pre If an assignment to {none} is made in a simulation with the {hybrid/overlay} pair style, it wipes out all previous assignments of that atom type pair to sub-styles. Note that you may need to use an "atom_style"_atom_style.html hybrid command in your input script, if atoms in the simulation will need attributes from several atom styles, due to using multiple pair potentials. :line Different force fields (e.g. CHARMM vs AMBER) may have different rules for applying weightings that change the strength of pairwise interactions bewteen pairs of atoms that are also 1-2, 1-3, and 1-4 neighbors in the molecular bond topology, as normally set by the "special_bonds"_special_bonds.html command. Different weights can be assigned to different pair hybrid sub-styles via the "pair_modify special"_pair_modify.html command. This allows multiple force fields to be used in a model of a hybrid system, however, there is no consistent approach to determine parameters automatically for the interactions between the two force fields, this is only recommended when particles described by the different force fields do not mix. Here is an example for mixing CHARMM and AMBER: The global {amber} setting sets the 1-4 interactions to non-zero scaling factors and then overrides them with 0.0 only for CHARMM: special_bonds amber pair_hybrid lj/charmm/coul/long 8.0 10.0 lj/cut/coul/long 10.0 pair_modify pair lj/charmm/coul/long special lj/coul 0.0 0.0 0.0 :pre The this input achieves the same effect: special_bonds 0.0 0.0 0.1 pair_hybrid lj/charmm/coul/long 8.0 10.0 lj/cut/coul/long 10.0 pair_modify pair lj/cut/coul/long special lj 0.0 0.0 0.5 pair_modify pair lj/cut/coul/long special coul 0.0 0.0 0.83333333 pair_modify pair lj/charmm/coul/long special lj/coul 0.0 0.0 0.0 :pre Here is an example for mixing Tersoff with OPLS/AA based on a data file that defines bonds for all atoms where for the Tersoff part of the system the force constants for the bonded interactions have been set to 0. Note the global settings are effectively {lj/coul 0.0 0.0 0.5} as required for OPLS/AA: special_bonds lj/coul 1e-20 1e-20 0.5 pair_hybrid tersoff lj/cut/coul/long 12.0 pair_modify pair tersoff special lj/coul 1.0 1.0 1.0 :pre See the "pair_modify"_pair_modify.html doc page for details on the specific syntax, requirements and restrictions. :line The potential energy contribution to the overall system due to an individual sub-style can be accessed and output via the "compute pair"_compute_pair.html command. :line NOTE: Several of the potentials defined via the pair_style command in LAMMPS are really many-body potentials, such as Tersoff, AIREBO, MEAM, ReaxFF, etc. The way to think about using these potentials in a hybrid setting is as follows. A subset of atom types is assigned to the many-body potential with a single "pair_coeff"_pair_coeff.html command, using "* *" to include all types and the NULL keywords described above to exclude specific types not assigned to that potential. If types 1,3,4 were assigned in that way (but not type 2), this means that all many-body interactions between all atoms of types 1,3,4 will be computed by that potential. Pair_style hybrid allows interactions between type pairs 2-2, 1-2, 2-3, 2-4 to be specified for computation by other pair styles. You could even add a second interaction for 1-1 to be computed by another pair style, assuming pair_style hybrid/overlay is used. But you should not, as a general rule, attempt to exclude the many-body interactions for some subset of the type pairs within the set of 1,3,4 interactions, e.g. exclude 1-1 or 1-3 interactions. That is not conceptually well-defined for many-body interactions, since the potential will typically calculate energies and foces for small groups of atoms, e.g. 3 or 4 atoms, using the neighbor lists of the atoms to find the additional atoms in the group. It is typically non-physical to think of excluding an interaction between a particular pair of atoms when the potential computes 3-body or 4-body interactions. However, you can still use the pair_coeff none setting or the "neigh_modify exclude"_neigh_modify.html command to exclude certain type pairs from the neighbor list that will be passed to a manybody sub-style. This will alter the calculations made by a many-body potential, since it builds its list of 3-body, 4-body, etc interactions from the pair list. You will need to think carefully as to whether it produces a physically meaningful result for your model. For example, imagine you have two atom types in your model, type 1 for atoms in one surface, and type 2 for atoms in the other, and you wish to use a Tersoff potential to compute interactions within each surface, but not between surfaces. Then either of these two command sequences would implement that model: pair_style hybrid tersoff pair_coeff * * tersoff SiC.tersoff C C pair_coeff 1 2 none :pre pair_style tersoff pair_coeff * * SiC.tersoff C C neigh_modify exclude type 1 2 :pre Either way, only neighbor lists with 1-1 or 2-2 interactions would be passed to the Tersoff potential, which means it would compute no 3-body interactions containing both type 1 and 2 atoms. Here is another example, using hybrid/overlay, to use 2 many-body potentials together, in an overlapping manner. Imagine you have CNT (C atoms) on a Si surface. You want to use Tersoff for Si/Si and Si/C interactions, and AIREBO for C/C interactions. Si atoms are type 1; C atoms are type 2. Something like this will work: pair_style hybrid/overlay tersoff airebo 3.0 pair_coeff * * tersoff SiC.tersoff.custom Si C pair_coeff * * airebo CH.airebo NULL C :pre Note that to prevent the Tersoff potential from computing C/C interactions, you would need to modify the SiC.tersoff file to turn off C/C interaction, i.e. by setting the appropriate coefficients to 0.0. :line Styles with a {gpu}, {intel}, {kk}, {omp}, or {opt} suffix are functionally the same as the corresponding style without the suffix. They have been optimized to run faster, depending on your available hardware, as discussed in "Section 5"_Section_accelerate.html of the manual. Since the {hybrid} and {hybrid/overlay} styles delegate computation to the individual sub-styles, the suffix versions of the {hybrid} and {hybrid/overlay} styles are used to propagate the corresponding suffix to all sub-styles, if those versions exist. Otherwise the non-accelerated version will be used. The individual accelerated sub-styles are part of the GPU, USER-OMP and OPT packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. You can specify the accelerated styles explicitly in your input script by including their suffix, or you can use the "-suffix command-line switch"_Section_start.html#start_7 when you invoke LAMMPS, or you can use the "suffix"_suffix.html command in your input script. See "Section 5"_Section_accelerate.html of the manual for more instructions on how to use the accelerated styles effectively. :line [Mixing, shift, table, tail correction, restart, rRESPA info]: Any pair potential settings made via the "pair_modify"_pair_modify.html command are passed along to all sub-styles of the hybrid potential. For atom type pairs I,J and I != J, if the sub-style assigned to I,I and J,J is the same, and if the sub-style allows for mixing, then the coefficients for I,J can be mixed. This means you do not have to specify a pair_coeff command for I,J since the I,J type pair will be assigned automatically to the sub-style defined for both I,I and J,J and its coefficients generated by the mixing rule used by that sub-style. For the {hybrid/overlay} style, there is an additional requirement that both the I,I and J,J pairs are assigned to a single sub-style. See the "pair_modify" command for details of mixing rules. See the See the doc page for the sub-style to see if allows for mixing. The hybrid pair styles supports the "pair_modify"_pair_modify.html shift, table, and tail options for an I,J pair interaction, if the associated sub-style supports it. For the hybrid pair styles, the list of sub-styles and their respective settings are written to "binary restart files"_restart.html, so a "pair_style"_pair_style.html command does not need to specified in an input script that reads a restart file. However, the coefficient information is not stored in the restart file. Thus, pair_coeff commands need to be re-specified in the restart input script. These pair styles support the use of the {inner}, {middle}, and {outer} keywords of the "run_style respa"_run_style.html command, if their sub-styles do. [Restrictions:] When using a long-range Coulombic solver (via the "kspace_style"_kspace_style.html command) with a hybrid pair_style, one or more sub-styles will be of the "long" variety, e.g. {lj/cut/coul/long} or {buck/coul/long}. You must insure that the short-range Coulombic cutoff used by each of these long pair styles is the same or else LAMMPS will generate an error. [Related commands:] "pair_coeff"_pair_coeff.html [Default:] none diff --git a/doc/src/pair_meam.txt b/doc/src/pair_meam.txt index a6e26e7cb..318f22067 100644 --- a/doc/src/pair_meam.txt +++ b/doc/src/pair_meam.txt @@ -1,371 +1,371 @@ "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 pair_style meam command :h3 [Syntax:] pair_style meam :pre [Examples:] pair_style meam pair_coeff * * ../potentials/library.meam Si ../potentials/si.meam Si pair_coeff * * ../potentials/library.meam Ni Al NULL Ni Al Ni Ni :pre [Description:] NOTE: The behavior of the MEAM potential for alloy systems has changed as of November 2010; see description below of the mixture_ref_t parameter Style {meam} computes pairwise interactions for a variety of materials using modified embedded-atom method (MEAM) potentials "(Baskes)"_#Baskes. Conceptually, it is an extension to the original "EAM potentials"_pair_eam.html which adds angular forces. It is thus suitable for modeling metals and alloys with fcc, bcc, hcp and diamond cubic structures, as well as covalently bonded materials like silicon and carbon. In the MEAM formulation, the total energy E of a system of atoms is given by: :c,image(Eqs/pair_meam.jpg) where F is the embedding energy which is a function of the atomic electron density rho, and phi is a pair potential interaction. The pair interaction is summed over all neighbors J of atom I within the cutoff distance. As with EAM, the multi-body nature of the MEAM potential is a result of the embedding energy term. Details of the computation of the embedding and pair energies, as implemented in LAMMPS, are given in "(Gullet)"_#Gullet and references therein. The various parameters in the MEAM formulas are listed in two files which are specified by the "pair_coeff"_pair_coeff.html command. These are ASCII text files in a format consistent with other MD codes that implement MEAM potentials, such as the serial DYNAMO code and Warp. Several MEAM potential files with parameters for different materials are included in the "potentials" directory of the LAMMPS distribution with a ".meam" suffix. All of these are parameterized in terms of LAMMPS "metal units"_units.html. Note that unlike for other potentials, cutoffs for MEAM potentials are not set in the pair_style or pair_coeff command; they are specified in the MEAM potential files themselves. Only a single pair_coeff command is used with the {meam} style which specifies two MEAM files and the element(s) to extract information for. The MEAM elements are mapped to LAMMPS atom types by specifying N additional arguments after the 2nd filename in the pair_coeff command, where N is the number of LAMMPS atom types: MEAM library file Elem1, Elem2, ... MEAM parameter file N element names = mapping of MEAM elements to atom types :ul See the "pair_coeff"_pair_coeff.html doc page for alternate ways to specify the path for the potential files. As an example, the potentials/library.meam file has generic MEAM settings for a variety of elements. The potentials/sic.meam file has specific parameter settings for a Si and C alloy system. If your LAMMPS simulation has 4 atoms types and you want the 1st 3 to be Si, and the 4th to be C, you would use the following pair_coeff command: pair_coeff * * library.meam Si C sic.meam Si Si Si C :pre The 1st 2 arguments must be * * so as to span all LAMMPS atom types. The two filenames are for the library and parameter file respectively. The Si and C arguments (between the file names) are the two elements for which info will be extracted from the library file. The first three trailing Si arguments map LAMMPS atom types 1,2,3 to the MEAM Si element. The final C argument maps LAMMPS atom type 4 to the MEAM C element. If the 2nd filename is specified as NULL, no parameter file is read, which simply means the generic parameters in the library file are used. Use of the NULL specification for the parameter file is discouraged for systems with more than a single element type (e.g. alloys), since the parameter file is expected to set element interaction terms that are not captured by the information in the library file. If a mapping value is specified as NULL, the mapping is not performed. This can be used when a {meam} potential is used as part of the {hybrid} pair style. The NULL values are placeholders for atom types that will be used with other potentials. The MEAM library file provided with LAMMPS has the name potentials/library.meam. It is the "meamf" file used by other MD codes. Aside from blank and comment lines (start with #) which can appear anywhere, it is formatted as a series of entries, each of which has 19 parameters and can span multiple lines: elt, lat, z, ielement, atwt, alpha, b0, b1, b2, b3, alat, esub, asub, t0, t1, t2, t3, rozero, ibar The "elt" and "lat" parameters are text strings, such as elt = Si or Cu and lat = dia or fcc. Because the library file is used by Fortran MD codes, these strings may be enclosed in single quotes, but this is not required. The other numeric parameters match values in the formulas above. The value of the "elt" string is what is used in the pair_coeff command to identify which settings from the library file you wish to read in. There can be multiple entries in the library file with the same "elt" value; LAMMPS reads the 1st matching entry it finds and ignores the rest. Other parameters in the MEAM library file correspond to single-element potential parameters: lat = lattice structure of reference configuration z = number of nearest neighbors in the reference structure ielement = atomic number atwt = atomic weight alat = lattice constant of reference structure esub = energy per atom (eV) in the reference structure at equilibrium asub = "A" parameter for MEAM (see e.g. "(Baskes)"_#Baskes) :pre The alpha, b0, b1, b2, b3, t0, t1, t2, t3 parameters correspond to the standard MEAM parameters in the literature "(Baskes)"_#Baskes (the b parameters are the standard beta parameters). The rozero parameter is an element-dependent density scaling that weights the reference background density (see e.g. equation 4.5 in "(Gullet)"_#Gullet) and is typically 1.0 for single-element systems. The ibar parameter selects the form of the function G(Gamma) used to compute the electron density; options are 0 => G = sqrt(1+Gamma) 1 => G = exp(Gamma/2) 2 => not implemented 3 => G = 2/(1+exp(-Gamma)) 4 => G = sqrt(1+Gamma) -5 => G = +-sqrt(abs(1+Gamma)) :pre If used, the MEAM parameter file contains settings that override or complement the library file settings. Examples of such parameter files are in the potentials directory with a ".meam" suffix. Their format is the same as is read by other Fortran MD codes. Aside from blank and comment lines (start with #) which can appear anywhere, each line has one of the following forms. Each line can also have a trailing comment (starting with #) which is ignored. keyword = value keyword(I) = value keyword(I,J) = value keyword(I,J,K) = value :pre The recognized keywords are as follows: Ec, alpha, rho0, delta, lattce, attrac, repuls, nn2, Cmin, Cmax, rc, delr, augt1, gsmooth_factor, re where rc = cutoff radius for cutoff function; default = 4.0 delr = length of smoothing distance for cutoff function; default = 0.1 rho0(I) = relative density for element I (overwrites value read from meamf file) Ec(I,J) = cohesive energy of reference structure for I-J mixture delta(I,J) = heat of formation for I-J alloy; if Ec_IJ is input as zero, then LAMMPS sets Ec_IJ = (Ec_II + Ec_JJ)/2 - delta_IJ alpha(I,J) = alpha parameter for pair potential between I and J (can be computed from bulk modulus of reference structure re(I,J) = equilibrium distance between I and J in the reference structure Cmax(I,J,K) = Cmax screening parameter when I-J pair is screened by K (I<=J); default = 2.8 Cmin(I,J,K) = Cmin screening parameter when I-J pair is screened by K (I<=J); default = 2.0 lattce(I,J) = lattice structure of I-J reference structure: dia = diamond (interlaced fcc for alloy) fcc = face centered cubic bcc = body centered cubic dim = dimer b1 = rock salt (NaCl structure) - hcp = hexagonal close-packed - c11 = MoSi2 structure - l12 = Cu3Au structure (lower case L, followed by 12) + hcp = hexagonal close-packed + c11 = MoSi2 structure + l12 = Cu3Au structure (lower case L, followed by 12) b2 = CsCl structure (interpenetrating simple cubic) nn2(I,J) = turn on second-nearest neighbor MEAM formulation for I-J pair (see for example "(Lee)"_#Lee). 0 = second-nearest neighbor formulation off 1 = second-nearest neighbor formulation on default = 0 attrac(I,J) = additional cubic attraction term in Rose energy I-J pair potential default = 0 repuls(I,J) = additional cubic repulsive term in Rose energy I-J pair potential default = 0 zbl(I,J) = blend the MEAM I-J pair potential with the ZBL potential for small atom separations "(ZBL)"_#ZBL default = 1 gsmooth_factor = factor determining the length of the G-function smoothing region; only significant for ibar=0 or ibar=4. 99.0 = short smoothing region, sharp step 0.5 = long smoothing region, smooth step default = 99.0 augt1 = integer flag for whether to augment t1 parameter by 3/5*t3 to account for old vs. new meam formulations; 0 = don't augment t1 1 = augment t1 default = 1 ialloy = integer flag to use alternative averaging rule for t parameters, for comparison with the DYNAMO MEAM code 0 = standard averaging (matches ialloy=0 in DYNAMO) 1 = alternative averaging (matches ialloy=1 in DYNAMO) 2 = no averaging of t (use single-element values) default = 0 mixture_ref_t = integer flag to use mixture average of t to compute the background reference density for alloys, instead of the single-element values (see description and warning elsewhere in this doc page) 0 = do not use mixture averaging for t in the reference density 1 = use mixture averaging for t in the reference density default = 0 erose_form = integer value to select the form of the Rose energy function (see description below). default = 0 emb_lin_neg = integer value to select embedding function for negative densities 0 = F(rho)=0 1 = F(rho) = -asub*esub*rho (linear in rho, matches DYNAMO) default = 0 bkgd_dyn = integer value to select background density formula 0 = rho_bkgd = rho_ref_meam(a) (as in the reference structure) 1 = rho_bkgd = rho0_meam(a)*Z_meam(a) (matches DYNAMO) default = 0 :pre Rc, delr, re are in distance units (Angstroms in the case of metal units). Ec and delta are in energy units (eV in the case of metal units). Each keyword represents a quantity which is either a scalar, vector, 2d array, or 3d array and must be specified with the correct corresponding array syntax. The indices I,J,K each run from 1 to N where N is the number of MEAM elements being used. Thus these lines rho0(2) = 2.25 alpha(1,2) = 4.37 :pre set rho0 for the 2nd element to the value 2.25 and set alpha for the alloy interaction between elements 1 and 2 to 4.37. The augt1 parameter is related to modifications in the MEAM formulation of the partial electron density function. In recent literature, an extra term is included in the expression for the third-order density in order to make the densities orthogonal (see for example "(Wang)"_#Wang, equation 3d); this term is included in the MEAM implementation in lammps. However, in earlier published work this term was not included when deriving parameters, including most of those provided in the library.meam file included with lammps, and to account for this difference the parameter t1 must be augmented by 3/5*t3. If augt1=1, the default, this augmentation is done automatically. When parameter values are fit using the modified density function, as in more recent literature, augt1 should be set to 0. The mixture_ref_t parameter is available to match results with those of previous versions of lammps (before January 2011). Newer versions of lammps, by default, use the single-element values of the t parameters to compute the background reference density. This is the proper way to compute these parameters. Earlier versions of lammps used an alloy mixture averaged value of t to compute the background reference density. Setting mixture_ref_t=1 gives the old behavior. WARNING: using mixture_ref_t=1 will give results that are demonstrably incorrect for second-neighbor MEAM, and non-standard for first-neighbor MEAM; this option is included only for matching with previous versions of lammps and should be avoided if possible. The parameters attrac and repuls, along with the integer selection parameter erose_form, can be used to modify the Rose energy function used to compute the pair potential. This function gives the energy of the reference state as a function of interatomic spacing. The form of this function is: astar = alpha * (r/re - 1.d0) if erose_form = 0: erose = -Ec*(1+astar+a3*(astar**3)/(r/re))*exp(-astar) if erose_form = 1: erose = -Ec*(1+astar+(-attrac+repuls/r)*(astar**3))*exp(-astar) if erose_form = 2: erose = -Ec*(1 +astar + a3*(astar**3))*exp(-astar) a3 = repuls, astar < 0 a3 = attrac, astar >= 0 :pre Most published MEAM parameter sets use the default values attrac=repulse=0. Setting repuls=attrac=delta corresponds to the form used in several recent published MEAM parameter sets, such as "(Valone)"_#Valone NOTE: The default form of the erose expression in LAMMPS was corrected in March 2009. The current version is correct, but may show different behavior compared with earlier versions of lammps with the attrac and/or repuls parameters are non-zero. To obtain the previous default form, use erose_form = 1 (this form does not seem to appear in the literature). An alternative form (see e.g. "(Lee2)"_#Lee2) is available using erose_form = 2. :line [Mixing, shift, table, tail correction, restart, rRESPA info]: For atom type pairs I,J and I != J, where types I and J correspond to two different element types, mixing is performed by LAMMPS with user-specifiable parameters as described above. You never need to specify a pair_coeff command with I != J arguments for this style. This pair style does not support the "pair_modify"_pair_modify.html shift, table, and tail options. This pair style does not write its information to "binary restart files"_restart.html, since it is stored in potential files. Thus, you need to re-specify the pair_style and pair_coeff commands in an input script that reads a restart file. This pair style can only be used via the {pair} keyword of the "run_style respa"_run_style.html command. It does not support the {inner}, {middle}, {outer} keywords. :line [Restrictions:] This style is part of the MEAM package. It is only enabled if LAMMPS was built with that package, which also requires the MEAM library be built and linked with LAMMPS. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. [Related commands:] "pair_coeff"_pair_coeff.html, "pair_style eam"_pair_eam.html, "pair_style meam/spline"_pair_meam_spline.html [Default:] none :line :link(Baskes) [(Baskes)] Baskes, Phys Rev B, 46, 2727-2742 (1992). :link(Gullet) [(Gullet)] Gullet, Wagner, Slepoy, SANDIA Report 2003-8782 (2003). This report may be accessed on-line via "this link"_sandreport. :link(sandreport,http://infoserve.sandia.gov/sand_doc/2003/038782.pdf) :link(Lee) [(Lee)] Lee, Baskes, Phys. Rev. B, 62, 8564-8567 (2000). :link(Lee2) [(Lee2)] Lee, Baskes, Kim, Cho. Phys. Rev. B, 64, 184102 (2001). :link(Valone) [(Valone)] Valone, Baskes, Martin, Phys. Rev. B, 73, 214209 (2006). :link(Wang) [(Wang)] Wang, Van Hove, Ross, Baskes, J. Chem. Phys., 121, 5410 (2004). :link(ZBL) [(ZBL)] J.F. Ziegler, J.P. Biersack, U. Littmark, "Stopping and Ranges of Ions in Matter", Vol 1, 1985, Pergamon Press. diff --git a/doc/src/pair_reax_c.txt b/doc/src/pair_reax_c.txt index d2d2643ff..bd8d7e44c 100644 --- a/doc/src/pair_reax_c.txt +++ b/doc/src/pair_reax_c.txt @@ -1,347 +1,349 @@ "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 pair_style reax/c command :h3 pair_style reax/c/kk command :h3 [Syntax:] pair_style reax/c cfile keyword value :pre cfile = NULL or name of a control file :ulb,l zero or more keyword/value pairs may be appended :l keyword = {checkqeq} or {lgvdw} or {safezone} or {mincap} {checkqeq} value = {yes} or {no} = whether or not to require qeq/reax fix {lgvdw} value = {yes} or {no} = whether or not to use a low gradient vdW correction {safezone} = factor used for array allocation {mincap} = minimum size for array allocation :pre :ule [Examples:] pair_style reax/c NULL pair_style reax/c controlfile checkqeq no pair_style reax/c NULL lgvdw yes pair_style reax/c NULL safezone 1.6 mincap 100 pair_coeff * * ffield.reax C H O N :pre [Description:] Style {reax/c} computes the ReaxFF potential of van Duin, Goddard and co-workers. ReaxFF uses distance-dependent bond-order functions to represent the contributions of chemical bonding to the potential energy. There is more than one version of ReaxFF. The version implemented in LAMMPS uses the functional forms documented in the supplemental information of the following paper: "(Chenoweth et al., 2008)"_#Chenoweth_2008. The version integrated into LAMMPS matches the most up-to-date version of ReaxFF as of summer 2010. For more technical details about the pair reax/c implementation of ReaxFF, see -the "(Aktulga)"_#Aktulga paper. +the "(Aktulga)"_#Aktulga paper. The {reax/c} style was initially +implemented as a stand-alone C code and is now integrated into LAMMPS +as a package. The {reax/c/kk} style is a Kokkos version of the ReaxFF potential that is derived from the {reax/c} style. The Kokkos version can run on GPUs and can also use OpenMP multithreading. For more information about the Kokkos package, see "Section 4"_Section_packages.html#kokkos and "Section 5.3.3"_accelerate_kokkos.html. One important consideration when using the {reax/c/kk} style is the choice of either half or full neighbor lists. This setting can be changed using the Kokkos "package"_package.html command. The {reax/c} style differs from the "pair_style reax"_pair_reax.html command in the lo-level implementation details. The {reax} style is a Fortran library, linked to LAMMPS. The {reax/c} style was initially implemented as stand-alone C code and is now integrated into LAMMPS as a package. LAMMPS provides several different versions of ffield.reax in its potentials dir, each called potentials/ffield.reax.label. These are documented in potentials/README.reax. The default ffield.reax contains parameterizations for the following elements: C, H, O, N. The format of these files is identical to that used originally by van Duin. We have tested the accuracy of {pair_style reax/c} potential against the original ReaxFF code for the systems mentioned above. You can use other ffield files for specific chemical systems that may be available elsewhere (but note that their accuracy may not have been tested). NOTE: We do not distribute a wide variety of ReaxFF force field files with LAMMPS. Adri van Duin's group at PSU is the central repository for this kind of data as they are continuously deriving and updating parameterizations for different classes of materials. You can submit a contact request at the Materials Computation Center (MCC) website "https://www.mri.psu.edu/materials-computation-center/connect-mcc"_https://www.mri.psu.edu/materials-computation-center/connect-mcc, describing the material(s) you are interested in modeling with ReaxFF. They can tell you what is currently available or what it would take to create a suitable ReaxFF parameterization. The {cfile} setting can be specified as NULL, in which case default settings are used. A control file can be specified which defines values of control variables. Some control variables are global parameters for the ReaxFF potential. Others define certain performance and output settings. Each line in the control file specifies the value for a control variable. The format of the control file is described below. NOTE: The LAMMPS default values for the ReaxFF global parameters correspond to those used by Adri van Duin's stand-alone serial code. If these are changed by setting control variables in the control file, the results from LAMMPS and the serial code will not agree. Two examples using {pair_style reax/c} are provided in the examples/reax sub-directory, along with corresponding examples for "pair_style reax"_pair_reax.html. Use of this pair style requires that a charge be defined for every atom. See the "atom_style"_atom_style.html and "read_data"_read_data.html commands for details on how to specify charges. The ReaxFF parameter files provided were created using a charge equilibration (QEq) model for handling the electrostatic interactions. Therefore, by default, LAMMPS requires that the "fix qeq/reax"_fix_qeq_reax.html command be used with {pair_style reax/c} when simulating a ReaxFF model, to equilibrate charge each timestep. Using the keyword {checkqeq} with the value {no} turns off the check for {fix qeq/reax}, allowing a simulation to be run without charge equilibration. In this case, the static charges you assign to each atom will be used for computing the electrostatic interactions in the system. See the "fix qeq/reax"_fix_qeq_reax.html command for details. Using the optional keyword {lgvdw} with the value {yes} turns on the low-gradient correction of the ReaxFF/C for long-range London Dispersion, as described in the "(Liu)"_#Liu_2011 paper. Force field file {ffield.reax.lg} is designed for this correction, and is trained for several energetic materials (see "Liu"). When using lg-correction, recommended value for parameter {thb} is 0.01, which can be set in the control file. Note: Force field files are different for the original or lg corrected pair styles, using wrong ffield file generates an error message. Optional keywords {safezone} and {mincap} are used for allocating reax/c arrays. Increasing these values can avoid memory problems, such as segmentation faults and bondchk failed errors, that could occur under certain conditions. These keywords aren't used by the Kokkos version, which instead uses a more robust memory allocation scheme that checks if the sizes of the arrays have been exceeded and automatically allocates more memory. The thermo variable {evdwl} stores the sum of all the ReaxFF potential energy contributions, with the exception of the Coulombic and charge equilibration contributions which are stored in the thermo variable {ecoul}. The output of these quantities is controlled by the "thermo"_thermo.html command. This pair style tallies a breakdown of the total ReaxFF potential energy into sub-categories, which can be accessed via the "compute pair"_compute_pair.html command as a vector of values of length 14. The 14 values correspond to the following sub-categories (the variable names in italics match those used in the original FORTRAN ReaxFF code): {eb} = bond energy {ea} = atom energy {elp} = lone-pair energy {emol} = molecule energy (always 0.0) {ev} = valence angle energy {epen} = double-bond valence angle penalty {ecoa} = valence angle conjugation energy {ehb} = hydrogen bond energy {et} = torsion energy {eco} = conjugation energy {ew} = van der Waals energy {ep} = Coulomb energy {efi} = electric field energy (always 0.0) {eqeq} = charge equilibration energy :ol To print these quantities to the log file (with descriptive column headings) the following commands could be included in an input script: compute reax all pair reax/c -variable eb equal c_reax\[1\] -variable ea equal c_reax\[2\] +variable eb equal c_reax\[1\] +variable ea equal c_reax\[2\] \[...\] -variable eqeq equal c_reax\[14\] -thermo_style custom step temp epair v_eb v_ea ... v_eqeq :pre +variable eqeq equal c_reax\[14\] +thermo_style custom step temp epair v_eb v_ea \[...\] v_eqeq :pre Only a single pair_coeff command is used with the {reax/c} style which specifies a ReaxFF potential file with parameters for all needed elements. These are mapped to LAMMPS atom types by specifying N additional arguments after the filename in the pair_coeff command, where N is the number of LAMMPS atom types: filename N indices = ReaxFF elements :ul The filename is the ReaxFF potential file. Unlike for the {reax} pair style, any filename can be used. In the ReaxFF potential file, near the top, after the general parameters, is the atomic parameters section that contains element names, each with a couple dozen numeric parameters. If there are M elements specified in the {ffield} file, think of these as numbered 1 to M. Each of the N indices you specify for the N atom types of LAMMPS atoms must be an integer from 1 to M. Atoms with LAMMPS type 1 will be mapped to whatever element you specify as the first index value, etc. If a mapping value is specified as NULL, the mapping is not performed. This can be used when the {reax/c} style is used as part of the {hybrid} pair style. The NULL values are placeholders for atom types that will be used with other potentials. As an example, say your LAMMPS simulation has 4 atom types and the elements are ordered as C, H, O, N in the {ffield} file. If you want the LAMMPS atom type 1 and 2 to be C, type 3 to be N, and type 4 to be H, you would use the following pair_coeff command: pair_coeff * * ffield.reax C C N H :pre :line The format of a line in the control file is as follows: variable_name value :pre and it may be followed by an "!" character and a trailing comment. If the value of a control variable is not specified, then default values are used. What follows is the list of variables along with a brief description of their use and default values. simulation_name: Output files produced by {pair_style reax/c} carry this name + extensions specific to their contents. Partial energies are reported with a ".pot" extension, while the trajectory file has ".trj" extension. tabulate_long_range: To improve performance, long range interactions can optionally be tabulated (0 means no tabulation). Value of this variable denotes the size of the long range interaction table. The range from 0 to long range cutoff (defined in the {ffield} file) is divided into {tabulate_long_range} points. Then at the start of simulation, we fill in the entries of the long range interaction table by computing the energies and forces resulting from van der Waals and Coulomb interactions between every possible atom type pairs present in the input system. During the simulation we consult to the long range interaction table to estimate the energy and forces between a pair of atoms. Linear interpolation is used for estimation. (default value = 0) energy_update_freq: Denotes the frequency (in number of steps) of writes into the partial energies file. (default value = 0) nbrhood_cutoff: Denotes the near neighbors cutoff (in Angstroms) regarding the bonded interactions. (default value = 5.0) hbond_cutoff: Denotes the cutoff distance (in Angstroms) for hydrogen -bond interactions.(default value = 7.5. Value of 0.0 turns off +bond interactions.(default value = 7.5. A value of 0.0 turns off hydrogen bonds) bond_graph_cutoff: is the threshold used in determining what is a physical bond, what is not. Bonds and angles reported in the trajectory file rely on this cutoff. (default value = 0.3) thb_cutoff: cutoff value for the strength of bonds to be considered in three body interactions. (default value = 0.001) thb_cutoff_sq: cutoff value for the strength of bond order products to be considered in three body interactions. (default value = 0.00001) write_freq: Frequency of writes into the trajectory file. (default value = 0) traj_title: Title of the trajectory - not the name of the trajectory file. atom_info: 1 means print only atomic positions + charge (default = 0) atom_forces: 1 adds net forces to atom lines in the trajectory file (default = 0) atom_velocities: 1 adds atomic velocities to atoms line (default = 0) bond_info: 1 prints bonds in the trajectory file (default = 0) angle_info: 1 prints angles in the trajectory file (default = 0) :line [Mixing, shift, table, tail correction, restart, rRESPA info]: This pair style does not support the "pair_modify"_pair_modify.html mix, shift, table, and tail options. This pair style does not write its information to "binary restart files"_restart.html, since it is stored in potential files. Thus, you need to re-specify the pair_style and pair_coeff commands in an input script that reads a restart file. This pair style can only be used via the {pair} keyword of the "run_style respa"_run_style.html command. It does not support the {inner}, {middle}, {outer} keywords. :line Styles with a {gpu}, {intel}, {kk}, {omp}, or {opt} suffix are functionally the same as the corresponding style without the suffix. They have been optimized to run faster, depending on your available hardware, as discussed in "Section 5"_Section_accelerate.html of the manual. The accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. These accelerated styles are part of the GPU, USER-INTEL, KOKKOS, USER-OMP and OPT packages, respectively. They are only enabled if LAMMPS was built with those packages. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. You can specify the accelerated styles explicitly in your input script by including their suffix, or you can use the "-suffix command-line switch"_Section_start.html#start_7 when you invoke LAMMPS, or you can use the "suffix"_suffix.html command in your input script. See "Section 5"_Section_accelerate.html of the manual for more instructions on how to use the accelerated styles effectively. :line [Restrictions:] This pair style is part of the USER-REAXC 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. The ReaxFF potential files provided with LAMMPS in the potentials directory are parameterized for real "units"_units.html. You can use the ReaxFF potential with any LAMMPS units, but you would need to create your own potential file with coefficients listed in the appropriate units if your simulation doesn't use "real" units. [Related commands:] "pair_coeff"_pair_coeff.html, "fix qeq/reax"_fix_qeq_reax.html, "fix reax/c/bonds"_fix_reax_bonds.html, "fix reax/c/species"_fix_reaxc_species.html, "pair_style reax"_pair_reax.html [Default:] The keyword defaults are checkqeq = yes, lgvdw = no, safezone = 1.2, mincap = 50. :line :link(Chenoweth_2008) [(Chenoweth_2008)] Chenoweth, van Duin and Goddard, Journal of Physical Chemistry A, 112, 1040-1053 (2008). :link(Aktulga) (Aktulga) Aktulga, Fogarty, Pandit, Grama, Parallel Computing, 38, 245-259 (2012). :link(Liu_2011) [(Liu)] L. Liu, Y. Liu, S. V. Zybin, H. Sun and W. A. Goddard, Journal of Physical Chemistry A, 115, 11016-11022 (2011). diff --git a/doc/src/pair_resquared.txt b/doc/src/pair_resquared.txt old mode 100755 new mode 100644 diff --git a/doc/src/pair_smtbq.txt b/doc/src/pair_smtbq.txt old mode 100755 new mode 100644 index e2868ae62..c70af68b3 --- a/doc/src/pair_smtbq.txt +++ b/doc/src/pair_smtbq.txt @@ -1,261 +1,261 @@ "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 pair_style smtbq command :h3 [Syntax:] pair_style smtbq :pre [Examples:] pair_style smtbq pair_coeff * * ffield.smtbq.Al2O3 O Al :pre [Description:] This pair stylecomputes a variable charge SMTB-Q (Second-Moment tight-Binding QEq) potential as described in "SMTB-Q_1"_#SMTB-Q_1 and "SMTB-Q_2"_#SMTB-Q_2. Briefly, the energy of metallic-oxygen systems is given by three contributions: :c,image(Eqs/pair_smtbq1.jpg) where {Etot} is the total potential energy of the system, {EES} is the electrostatic part of the total energy, {EOO} is the interaction between oxygens and {EMO} is a short-range interaction between metal and oxygen atoms. This interactions depend on interatomic distance {rij} and/or the charge {Qi} of atoms {i}. Cut-off function enables smooth convergence to zero interaction. The parameters appearing in the upper expressions are set in the ffield.SMTBQ.Syst file where Syst corresponds to the selected system (e.g. field.SMTBQ.Al2O3). Exemples for TiO2, Al2O3 are provided. A single pair_coeff command is used with the SMTBQ styles which provides the path to the potential file with parameters for needed elements. These are mapped to LAMMPS atom types by specifying additional arguments after the potential filename in the pair_coeff command. Note that atom type 1 must always correspond to oxygen atoms. As an example, to simulate a TiO2 system, atom type 1 has to be oxygen and atom type 2 Ti. The following pair_coeff command should then be used: pair_coeff * * PathToLammps/potentials/ffield.smtbq.TiO2 O Ti :pre The electrostatic part of the energy consists of two components : self-energy of atom {i} in the form of a second order charge dependent polynomial and a long-range Coulombic electrostatic interaction. The latter uses the wolf summation method described in "Wolf"_#Wolf, spherically truncated at a longer cutoff, {Rcoul}. The charge of each ion is modeled by an orbital Slater which depends on the principal quantum number ({n}) of the outer orbital shared by the ion. Interaction between oxygen, {EOO}, consists of two parts, an attractive and a repulsive part. The attractive part is effective only at short range (< r2OO). The attractive contribution was optimized to study surfaces reconstruction (e.g. "SMTB-Q_2"_#SMTB-Q_2 in TiO2) and is not necessary for oxide bulk modeling. The repulsive part is the Pauli interaction between the electron clouds of oxygen. The Pauli repulsion and the coulombic electrostatic interaction have same cut off value. In the ffield.SMTBQ.Syst, the keyword {'buck'} allows to consider only the repulsive O-O interactions. The keyword {'buckPlusAttr'} allows to consider the repulsive and the attractive O-O interactions. The short-range interaction between metal-oxygen, {EMO} is based on the second moment approximation of the density of states with a N-body potential for the band energy term, {Eicov}, and a Born-Mayer type repulsive terms as indicated by the keyword {'second_moment'} in the ffield.SMTBQ.Syst. The energy band term is given by: :c,image(Eqs/pair_smtbq2.jpg) where {ηi} is the stoichiometry of atom {i}, {δQi} is the charge delocalization of atom {i}, compared to its formal charge {QFi}. n0, the number of hybridized orbitals, is calculated with to the atomic orbitals shared {di} and the stoichiometry {ηi}. {rc1} and {rc2} are the two cutoff radius around the fourth neighbors in the cutoff function. In the formalism used here, {ξ0} is the energy parameter. {ξ0} is in tight-binding approximation the hopping integral between the hybridized orbitals of the cation and the anion. In the literature we find many ways to write the hopping integral depending on whether one takes the point of view of the anion or cation. These are equivalent vision. The correspondence between the two visions is explained in appendix A of the article in the SrTiO3 "SMTB-Q_3"_#SMTB-Q_3 (parameter {β} shown in this article is in fact the {βO}). To summarize the relationship between the hopping integral {ξ0} and the others, we have in an oxide CnOm the following relationship: :c,image(Eqs/pair_smtbq3.jpg) Thus parameter μ, indicated above, is given by : μ = (√n + √m) ⁄ 2 The potential offers the possibility to consider the polarizability of the electron clouds of oxygen by changing the slater radius of the charge density around the oxygens through the parameters {rBB, rB and rS} in the ffield.SMTBQ.Syst. This change in radius is performed according to the method developed by E. Maras "SMTB-Q_2"_#SMTB-Q_2. This method needs to determine the number of nearest neighbors around the oxygen. This calculation is based on first ({r1n}) and second ({r2n}) distances neighbors. The SMTB-Q potential is a variable charge potential. The equilibrium charge on each atom is calculated by the electronegativity equalization (QEq) method. See "Rick"_#Rick for further detail. One can adjust the frequency, the maximum number of iterative loop and the convergence of the equilibrium charge calculation. To obtain the energy conservation in NVE thermodynamic ensemble, we recommend to use a convergence parameter in the interval 10-5 - 10-6 eV. The ffield.SMTBQ.Syst files are provided for few systems. They consist of nine parts and the lines beginning with '#' are comments (note that the number of comment lines matter). The first sections are on the potential parameters and others are on the simulation options and might be modified. Keywords are character type and must be enclosed in quotation marks (''). 1) Number of different element in the oxide: Nelem= 2 or 3 Divided line :ul 2) Atomic parameters For the anion (oxygen) : Name of element (char) and stoichiometry in oxide Formal charge and mass of element Principal quantic number of outer orbital ({n}), electronegativity ({χ0i}) and hardness ({J0i}) Ionic radius parameters : max coordination number ({coordBB} = 6 by default), bulk coordination number {(coordB)}, surface coordination number {(coordS)} and {rBB, rB and rS} the slater radius for each coordination number. (note : If you don't want to change the slater radius, use three identical radius values) Number of orbital shared by the element in the oxide ({di}) Divided line :ul For each cations (metal): Name of element (char) and stoichiometry in oxide Formal charge and mass of element Number of electron in outer orbital {(ne)}, electronegativity ({χ0i}), hardness ({J0i}) and {rSalter} the slater radius for the cation. Number of orbitals shared by the elements in the oxide ({di}) Divided line :ul 3) Potential parameters: Keyword for element1, element2 and interaction potential ('second_moment' or 'buck' or 'buckPlusAttr') between element 1 and 2. If the potential is 'second_moment', specify 'oxide' or 'metal' for metal-oxygen or metal-metal interactions respectively. -Potential parameter:

If type of potential is 'second_moment' : {A (eV)}, {p}, {ξ0} (eV) and {q}
{rc1} (Å), {rc2} (Å) and {r0} (Å)
If type of potential is 'buck' : {C} (eV) and {ρ} (Å)
If type of potential is 'buckPlusAttr' : {C} (eV) and {ρ} (Å)
{D} (eV), {B} (Å-1), {r1OO} (Å) and {r2OO} (Å)
+Potential parameter:

If type of potential is 'second_moment' : {A (eV)}, {p}, {ξ0} (eV) and {q}
{rc1} (Å), {rc2} (Å) and {r0} (Å)
If type of potential is 'buck' : {C} (eV) and {ρ} (Å)
If type of potential is 'buckPlusAttr' : {C} (eV) and {ρ} (Å)
{D} (eV), {B} (Å-1), {r1OO} (Å) and {r2OO} (Å)
Divided line :ul 4) Tables parameters: Cutoff radius for the Coulomb interaction ({Rcoul}) Starting radius ({rmin} = 1,18845 Å) and increments ({dr} = 0,001 Å) for creating the potential table. Divided line :ul 5) Rick model parameter: {Nevery} : parameter to set the frequency ({1/Nevery}) of the charge resolution. The charges are evaluated each {Nevery} time steps. Max number of iterative loop ({loopmax}) and precision criterion ({prec}) in eV of the charge resolution Divided line :ul 6) Coordination parameter: First ({r1n}) and second ({r2n}) neighbor distances in Å Divided line :ul 7) Charge initialization mode: Keyword ({QInitMode}) and initial oxygen charge ({Qinit}). If keyword = 'true', all oxygen charges are initially set equal to {Qinit}. The charges on the cations are initially set in order to respect the neutrality of the box. If keyword = 'false', all atom charges are initially set equal to 0 if you use "create_atom"#create_atom command or the charge specified in the file structure using "read_data"_read_data.html command. Divided line :ul 8) Mode for the electronegativity equalization (Qeq) : -Keyword mode:
 
QEqAll (one QEq group) | no parameters
QEqAllParallel (several QEq groups) | no parameters
Surface | zlim (QEq only for z>zlim)
+Keyword mode:
 
QEqAll (one QEq group) | no parameters
QEqAllParallel (several QEq groups) | no parameters
Surface | zlim (QEq only for z>zlim)
Parameter if necessary Divided line :ul 9) Verbose : If you want the code to work in verbose mode or not : 'true' or 'false' If you want to print or not in file 'Energy_component.txt' the three main contributions to the energy of the system according to the description presented above : 'true' or 'false' and {NEnergy}. This option writes in file every {NEnergy} time step. If the value is 'false' then {NEnergy} = 0. The file take into account the possibility to have several QEq group {g} then it writes: time step, number of atoms in group {g}, electrostatic part of energy, {EES}, the interaction between oxygen, {EOO}, and short range metal-oxygen interaction, {EMO}. If you want to print in file 'Electroneg_component.txt' the electronegativity component ({∂Etot ⁄∂Qi}) or not: 'true' or 'false' and {NElectroneg}.This option writes in file every {NElectroneg} time step. If the value is 'false' then {NElectroneg} = 0. The file consist in atom number {i}, atom type (1 for oxygen and # higher than 1 for metal), atom position: {x}, {y} and {z}, atomic charge of atom {i}, electrostatic part of atom {i} electronegativity, covalent part of atom {i} electronegativity, the hopping integral of atom {i} {(Zβ2)i} and box electronegativity. :ul NOTE: This last option slows down the calculation dramatically. Use only with a single processor simulation. :line [Mixing, shift, table, tail correction, restart, rRESPA info:] This pair style does not support the "pair_modify"_pair_modify.html mix, shift, table, and tail options. This pair style does not write its information to "binary restart files"_restart.html, since it is stored in potential files. Thus, you needs to re-specify the pair_style and pair_coeff commands in an input script that reads a restart file. This pair style can only be used via the {pair} keyword of the "run_style respa"_run_style.html command. It does not support the {inner}, {middle}, {outer} keywords. :line [Restriction:] This pair style is part of the USER-SMTBQ package and is only enabled if LAMMPS is built with that package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. This potential requires using atom type 1 for oxygen and atom type higher than 1 for metal atoms. This pair style requires the "newton"_newton.html setting to be "on" for pair interactions. The SMTB-Q potential files provided with LAMMPS (see the potentials directory) are parameterized for metal "units"_units.html. :line [Citing this work:] Please cite related publication: N. Salles, O. Politano, E. Amzallag and R. Tetot, Comput. Mater. Sci. 111 (2016) 181-189 :line :link(SMTB-Q_1) [(SMTB-Q_1)] N. Salles, O. Politano, E. Amzallag, R. Tetot, Comput. Mater. Sci. 111 (2016) 181-189 :link(SMTB-Q_2) [(SMTB-Q_2)] E. Maras, N. Salles, R. Tetot, T. Ala-Nissila, H. Jonsson, J. Phys. Chem. C 2015, 119, 10391-10399 :link(SMTB-Q_3) [(SMTB-Q_3)] R. Tetot, N. Salles, S. Landron, E. Amzallag, Surface Science 616, 19-8722 28 (2013) :link(Wolf) [(Wolf)] D. Wolf, P. Keblinski, S. R. Phillpot, J. Eggebrecht, J Chem Phys, 110, 8254 (1999). :link(Rick) [(Rick)] S. W. Rick, S. J. Stuart, B. J. Berne, J Chem Phys 101, 6141 (1994). diff --git a/doc/src/pair_snap.txt b/doc/src/pair_snap.txt index f27dce6fa..734cdaa99 100644 --- a/doc/src/pair_snap.txt +++ b/doc/src/pair_snap.txt @@ -1,193 +1,193 @@ "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 pair_style snap command :h3 [Syntax:] pair_style snap :pre [Examples:] pair_style snap pair_coeff * * snap InP.snapcoeff In P InP.snapparam In In P P :pre [Description:] Style {snap} computes interactions using the spectral neighbor analysis potential (SNAP) "(Thompson)"_#Thompson2014. Like the GAP framework of Bartok et al. "(Bartok2010)"_#Bartok2010, "(Bartok2013)"_#Bartok2013 it uses bispectrum components to characterize the local neighborhood of each atom in a very general way. The mathematical definition of the bispectrum calculation used by SNAP is identical to that used of "compute sna/atom"_compute_sna_atom.html. In SNAP, the total energy is decomposed into a sum over atom energies. The energy of atom {i} is expressed as a weighted sum over bispectrum components. :c,image(Eqs/pair_snap.jpg) where {B_k^i} is the {k}-th bispectrum component of atom {i}, and {beta_k^alpha_i} is the corresponding linear coefficient that depends on {alpha_i}, the SNAP element of atom {i}. The number of bispectrum components used and their definitions depend on the values of {twojmax} and {diagonalstyle} defined in the SNAP parameter file described below. The bispectrum calculation is described in more detail in "compute sna/atom"_compute_sna_atom.html. Note that unlike for other potentials, cutoffs for SNAP potentials are not set in the pair_style or pair_coeff command; they are specified in the SNAP potential files themselves. Only a single pair_coeff command is used with the {snap} style which specifies two SNAP files and the list SNAP element(s) to be extracted. The SNAP elements are mapped to LAMMPS atom types by specifying N additional arguments after the 2nd filename in the pair_coeff command, where N is the number of LAMMPS atom types: SNAP element file Elem1, Elem2, ... SNAP parameter file N element names = mapping of SNAP elements to atom types :ul As an example, if a LAMMPS indium phosphide simulation has 4 atoms types, with the first two being indium and the 3rd and 4th being phophorous, the pair_coeff command would look like this: pair_coeff * * snap InP.snapcoeff In P InP.snapparam In In P P :pre The 1st 2 arguments must be * * so as to span all LAMMPS atom types. The two filenames are for the element and parameter files, respectively. The 'In' and 'P' arguments (between the file names) are the two elements which will be extracted from the element file. The two trailing 'In' arguments map LAMMPS atom types 1 and 2 to the SNAP 'In' element. The two trailing 'P' arguments map LAMMPS atom types 3 and 4 to the SNAP 'P' element. If a SNAP mapping value is specified as NULL, the mapping is not performed. This can be used when a {snap} potential is used as part of the {hybrid} pair style. The NULL values are placeholders for atom types that will be used with other potentials. The name of the SNAP element file usually ends in the ".snapcoeff" extension. It may contain coefficients for many SNAP elements. Only those elements listed in the pair_coeff command are extracted. The name of the SNAP parameter file usually ends in the ".snapparam" extension. It contains a small number of parameters that define the overall form of the SNAP potential. See the "pair_coeff"_pair_coeff.html doc page for alternate ways to specify the path for these files. Quite commonly, SNAP potentials are combined with one or more other LAMMPS pair styles using the {hybrid/overlay} pair style. As an example, the SNAP tantalum potential provided in the LAMMPS potentials directory combines the {snap} and {zbl} pair styles. It is invoked by the following commands: - variable zblcutinner equal 4 - variable zblcutouter equal 4.8 - variable zblz equal 73 - pair_style hybrid/overlay & - zbl $\{zblcutinner\} $\{zblcutouter\} snap - pair_coeff * * zbl 0.0 - pair_coeff 1 1 zbl $\{zblz\} - pair_coeff * * snap ../potentials/Ta06A.snapcoeff Ta & - ../potentials/Ta06A.snapparam Ta :pre + variable zblcutinner equal 4 + variable zblcutouter equal 4.8 + variable zblz equal 73 + pair_style hybrid/overlay & + zbl $\{zblcutinner\} $\{zblcutouter\} snap + pair_coeff * * zbl 0.0 + pair_coeff 1 1 zbl $\{zblz\} + pair_coeff * * snap ../potentials/Ta06A.snapcoeff Ta & + ../potentials/Ta06A.snapparam Ta :pre It is convenient to keep these commands in a separate file that can be inserted in any LAMMPS input script using the "include"_include.html command. The top of the SNAP element file can contain any number of blank and comment lines (start with #), but follows a strict format after that. The first non-blank non-comment line must contain two integers: nelem = Number of elements ncoeff = Number of coefficients :ul This is followed by one block for each of the {nelem} elements. The first line of each block contains three entries: Element symbol (text string) R = Element radius (distance units) w = Element weight (dimensionless) :ul This line is followed by {ncoeff} coefficients, one per line. The SNAP parameter file can contain blank and comment lines (start with #) anywhere. Each non-blank non-comment line must contain one keyword/value pair. The required keywords are {rcutfac} and {twojmax}. Optional keywords are {rfac0}, {rmin0}, {diagonalstyle}, and {switchflag}. The default values for these keywords are {rfac0} = 0.99363 {rmin0} = 0.0 {diagonalstyle} = 3 {switchflag} = 0 :ul Detailed definitions of these keywords are given on the "compute sna/atom"_compute_sna_atom.html doc page. :line [Mixing, shift, table, tail correction, restart, rRESPA info]: For atom type pairs I,J and I != J, where types I and J correspond to two different element types, mixing is performed by LAMMPS with user-specifiable parameters as described above. You never need to specify a pair_coeff command with I != J arguments for this style. This pair style does not support the "pair_modify"_pair_modify.html shift, table, and tail options. This pair style does not write its information to "binary restart files"_restart.html, since it is stored in potential files. Thus, you need to re-specify the pair_style and pair_coeff commands in an input script that reads a restart file. This pair style can only be used via the {pair} keyword of the "run_style respa"_run_style.html command. It does not support the {inner}, {middle}, {outer} keywords. :line [Restrictions:] This style is part of the SNAP 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. [Related commands:] "compute sna/atom"_compute_sna_atom.html, "compute snad/atom"_compute_sna_atom.html, "compute snav/atom"_compute_sna_atom.html [Default:] none :line :link(Thompson2014) [(Thompson)] Thompson, Swiler, Trott, Foiles, Tucker, under review, preprint available at "arXiv:1409.3880"_http://arxiv.org/abs/1409.3880 :link(Bartok2010) [(Bartok2010)] Bartok, Payne, Risi, Csanyi, Phys Rev Lett, 104, 136403 (2010). :link(Bartok2013) [(Bartok2013)] Bartok, Gillan, Manby, Csanyi, Phys Rev B 87, 184115 (2013). diff --git a/doc/src/replicate.txt b/doc/src/replicate.txt index 218963b17..2e7153e38 100644 --- a/doc/src/replicate.txt +++ b/doc/src/replicate.txt @@ -1,85 +1,88 @@ "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 replicate command :h3 [Syntax:] replicate nx ny nz :pre nx,ny,nz = replication factors in each dimension :ul [Examples:] replicate 2 3 2 :pre [Description:] Replicate the current simulation one or more times in each dimension. For example, replication factors of 2,2,2 will create a simulation with 8x as many atoms by doubling the simulation domain in each dimension. A replication factor of 1 in a dimension leaves the simulation domain unchanged. When the new simulation box is created it is also partitioned into a regular 3d grid of rectangular bricks, one per processor, based on the number of processors being used and the settings of the "processors"_processors.html command. The partitioning can later be changed by the "balance"_balance.html or "fix balance"_fix_balance.html commands. All properties of the atoms are replicated, including their velocities, which may or may not be desirable. New atom IDs are assigned to new atoms, as are molecule IDs. Bonds and other topology interactions are created between pairs of new atoms as well as between old and new atoms. This is done by using the image flag for each atom to "unwrap" it out of the periodic box before replicating it. This means that any molecular bond you specify in the original data file that crosses a periodic boundary should be between two atoms with image flags that differ by 1. This will allow the bond to be unwrapped appropriately. [Restrictions:] A 2d simulation cannot be replicated in the z dimension. If a simulation is non-periodic in a dimension, care should be used when replicating it in that dimension, as it may put atoms nearly on top of each other. NOTE: You cannot use the replicate command on a system which has a molecule that spans the box and is bonded to itself across a periodic boundary, so that the molecule is efffectively a loop. A simple example would be a linear polymer chain that spans the simulation box and bonds back to itself across the periodic boundary. More realistic examples would be a CNT (meant to be an infinitely long CNT) or a graphene sheet or a bulk periodic crystal where there are explicit bonds specified between near neighbors. (Note that this only applies to systems that have permanent bonds as specified in the data file. A CNT that is just atoms modeled with the "AIREBO potential"_pair_airebo.html has no such permanent bonds, so it can be replicated.) The reason replication does not work with those systems is that the image flag settings described above cannot be made consistent. I.e. it is not possible to define images flags so that when every pair of bonded atoms is unwrapped (using the image flags), they will be close to each other. The only way the replicate command could work in this scenario is for it to break a bond, insert more atoms, and re-connect the loop for the larger simulation box. But it is not clever enough to do this. So you will have to construct a larger version of your molecule as a pre-processing step and input a new data file to LAMMPS. If the current simulation was read in from a restart file (before a -run is performed), there can have been no fix information stored in +run is performed), there must not be any fix information stored in the file for individual atoms. Similarly, no fixes can be defined at the time the replicate command is used that require vectors of atom information to be stored. This is because the replicate command does not know how to replicate that information for new atoms it creates. +To work around this restriction, restart files may be converted into +data files and fixes may be undefined via the "unfix"_unfix.html +command before and redefined after the replicate command. [Related commands:] none [Default:] none diff --git a/doc/src/restart.txt b/doc/src/restart.txt index 38bf79d36..3154465f6 100644 --- a/doc/src/restart.txt +++ b/doc/src/restart.txt @@ -1,174 +1,174 @@ "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 restart command :h3 [Syntax:] restart 0 restart N root keyword value ... restart N file1 file2 keyword value ... :pre N = write a restart file every this many timesteps :ulb,l N can be a variable (see below) :l root = filename to which timestep # is appended :l file1,file2 = two full filenames, toggle between them when writing file :l zero or more keyword/value pairs may be appended :l keyword = {fileper} or {nfile} :l {fileper} arg = Np Np = write one file for every this many processors {nfile} arg = Nf Nf = write this many files, one from each of Nf processors :pre :ule [Examples:] restart 0 restart 1000 poly.restart restart 1000 poly.restart.mpiio restart 1000 restart.*.equil restart 10000 poly.%.1 poly.%.2 nfile 10 restart v_mystep poly.restart :pre [Description:] Write out a binary restart file with the current state of the simulation every so many timesteps, in either or both of two modes, as a run proceeds. A value of 0 means do not write out any restart files. The two modes are as follows. If one filename is specified, a series of filenames will be created which include the timestep in the filename. If two filenames are specified, only 2 restart files will be created, with those names. LAMMPS will toggle between the 2 names as it writes successive restart files. Note that you can specify the restart command twice, once with a single filename and once with two filenames. This would allow you, for example, to write out archival restart files every 100000 steps using a single filenname, and more frequent temporary restart files every 1000 steps, using two filenames. Using restart 0 will turn off both modes of output. Similar to "dump"_dump.html files, the restart filename(s) can contain two wild-card characters. If a "*" appears in the single filename, it is replaced with the current timestep value. This is only recognized when a single filename is used (not when toggling back and forth). Thus, the 3rd example above creates restart files as follows: restart.1000.equil, restart.2000.equil, etc. If a single filename is used with no "*", then the timestep value is appended. E.g. the 2nd example above creates restart files as follows: poly.restart.1000, poly.restart.2000, etc. If a "%" character appears in the restart filename(s), then one file is written for each processor and the "%" character is replaced with the processor ID from 0 to P-1. An additional file with the "%" replaced by "base" is also written, which contains global information. For example, the files written on step 1000 for filename restart.% would be restart.base.1000, restart.0.1000, restart.1.1000, ..., restart.P-1.1000. This creates smaller files and can be a fast mode of output and subsequent input on parallel machines that support parallel I/O. The optional {fileper} and {nfile} keywords discussed below can alter the number of files written. The restart file can also be written in parallel as one large binary file via the MPI-IO library, which is part of the MPI standard for versions 2.0 and above. Using MPI-IO requires two steps. First, build LAMMPS with its MPIIO package installed, e.g. make yes-mpiio # installs the MPIIO package make mpi # build LAMMPS for your platform :pre Second, use a restart filename which contains ".mpiio". Note that it does not have to end in ".mpiio", just contain those characters. Unlike MPI-IO dump files, a particular restart file must be both written and read using MPI-IO. Restart files are written on timesteps that are a multiple of N but not on the first timestep of a run or minimization. You can use the "write_restart"_write_restart.html command to write a restart file before a run begins. A restart file is not written on the last timestep of a run unless it is a multiple of N. A restart file is written on the last timestep of a minimization if N > 0 and the minimization converges. Instead of a numeric value, N can be specifed as an "equal-style variable"_variable.html, which should be specified as v_name, where name is the variable name. In this case, the variable is evaluated at the beginning of a run to determine the next timestep at which a restart file will be written out. On that timestep, the variable will be evaluated again to determine the next timestep, etc. Thus the variable should return timestep values. See the stagger() and logfreq() and stride() math functions for "equal-style variables"_variable.html, as examples of useful functions to use in this context. Other similar math functions could easily be added as options for "equal-style variables"_variable.html. For example, the following commands will write restart files every step from 1100 to 1200, and could be useful for debugging a simulation where something goes wrong at step 1163: -variable s equal stride(1100,1200,1) -restart v_s tmp.restart :pre +variable s equal stride(1100,1200,1) +restart v_s tmp.restart :pre :line See the "read_restart"_read_restart.html command for information about what is stored in a restart file. Restart files can be read by a "read_restart"_read_restart.html command to restart a simulation from a particular state. Because the file is binary (to enable exact restarts), it may not be readable on another machine. In this case, you can use the "-r command-line switch"_Section_start.html#start_7 to convert a restart file to a data file. NOTE: Although the purpose of restart files is to enable restarting a simulation from where it left off, not all information about a simulation is stored in the file. For example, the list of fixes that were specified during the initial run is not stored, which means the new input script must specify any fixes you want to use. Even when restart information is stored in the file, as it is for some fixes, commands may need to be re-specified in the new input script, in order to re-use that information. See the "read_restart"_read_restart.html command for information about what is stored in a restart file. :line The optional {nfile} or {fileper} keywords can be used in conjunction with the "%" wildcard character in the specified restart file name(s). As explained above, the "%" character causes the restart file to be written in pieces, one piece for each of P processors. By default P = the number of processors the simulation is running on. The {nfile} or {fileper} keyword can be used to set P to a smaller value, which can be more efficient when running on a large number of processors. The {nfile} keyword sets P to the specified Nf value. For example, if Nf = 4, and the simulation is running on 100 processors, 4 files will be written, by processors 0,25,50,75. Each will collect information from itself and the next 24 processors and write it to a restart file. For the {fileper} keyword, the specified value of Np means write one file for every Np processors. For example, if Np = 4, every 4th processor (0,4,8,12,etc) will collect information from itself and the next 3 processors and write it to a restart file. :line [Restrictions:] To write and read restart files in parallel with MPI-IO, the MPIIO package must be installed. [Related commands:] "write_restart"_write_restart.html, "read_restart"_read_restart.html [Default:] restart 0 :pre diff --git a/doc/src/run.txt b/doc/src/run.txt index d6acee4f5..7f61f7bd6 100644 --- a/doc/src/run.txt +++ b/doc/src/run.txt @@ -1,206 +1,206 @@ "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 run command :h3 [Syntax:] run N keyword values ... :pre N = # of timesteps :ulb,l zero or more keyword/value pairs may be appended :l keyword = {upto} or {start} or {stop} or {pre} or {post} or {every} :l {upto} value = none {start} value = N1 N1 = timestep at which 1st run started {stop} value = N2 N2 = timestep at which last run will end {pre} value = {no} or {yes} {post} value = {no} or {yes} {every} values = M c1 c2 ... M = break the run into M-timestep segments and invoke one or more commands between each segment c1,c2,...,cN = one or more LAMMPS commands, each enclosed in quotes c1 = NULL means no command will be invoked :pre :ule [Examples:] run 10000 run 1000000 upto run 100 start 0 stop 1000 run 1000 pre no post yes run 100000 start 0 stop 1000000 every 1000 "print 'Protein Rg = $r'" run 100000 every 1000 NULL :pre [Description:] Run or continue dynamics for a specified number of timesteps. When the "run style"_run_style.html is {respa}, N refers to outer loop (largest) timesteps. A value of N = 0 is acceptable; only the thermodynamics of the system are computed and printed without taking a timestep. The {upto} keyword means to perform a run starting at the current timestep up to the specified timestep. E.g. if the current timestep is 10,000 and "run 100000 upto" is used, then an additional 90,000 timesteps will be run. This can be useful for very long runs on a machine that allocates chunks of time and terminate your job when time is exceeded. If you need to restart your script multiple times (reading in the last restart file), you can keep restarting your script with the same run command until the simulation finally completes. The {start} or {stop} keywords can be used if multiple runs are being performed and you want a "fix"_fix.html command that changes some value over time (e.g. temperature) to make the change across the entire set of runs and not just a single run. See the doc page for individual fixes to see which ones can be used with the {start/stop} keywords. For example, consider this fix followed by 10 run commands: -fix 1 all nvt 200.0 300.0 1.0 -run 1000 start 0 stop 10000 -run 1000 start 0 stop 10000 +fix 1 all nvt 200.0 300.0 1.0 +run 1000 start 0 stop 10000 +run 1000 start 0 stop 10000 ... -run 1000 start 0 stop 10000 :pre +run 1000 start 0 stop 10000 :pre The NVT fix ramps the target temperature from 200.0 to 300.0 during a run. If the run commands did not have the start/stop keywords (just "run 1000"), then the temperature would ramp from 200.0 to 300.0 during the 1000 steps of each run. With the start/stop keywords, the ramping takes place over the 10000 steps of all runs together. The {pre} and {post} keywords can be used to streamline the setup, clean-up, and associated output to the screen that happens before and after a run. This can be useful if you wish to do many short runs in succession (e.g. LAMMPS is being called as a library which is doing other computations between successive short LAMMPS runs). By default (pre and post = yes), LAMMPS creates neighbor lists, computes forces, and imposes fix constraints before every run. And after every run it gathers and prints timings statistics. If a run is just a continuation of a previous run (i.e. no settings are changed), the initial computation is not necessary; the old neighbor list is still valid as are the forces. So if {pre} is specified as "no" then the initial setup is skipped, except for printing thermodynamic info. Note that if {pre} is set to "no" for the very 1st run LAMMPS performs, then it is overridden, since the initial setup computations must be done. NOTE: If your input script changes the system between 2 runs, then the initial setup must be performed to insure the change is recognized by all parts of the code that are affected. Examples are adding a "fix"_fix.html or "dump"_dump.html or "compute"_compute.html, changing a "neighbor"_neigh_modify.html list parameter, or writing restart file which can migrate atoms between processors. LAMMPS has no easy way to check if this has happened, but it is an error to use the {pre no} option in this case. If {post} is specified as "no", the full timing summary is skipped; only a one-line summary timing is printed. The {every} keyword provides a means of breaking a LAMMPS run into a series of shorter runs. Optionally, one or more LAMMPS commands (c1, c2, ..., cN) will be executed in between the short runs. If used, the {every} keyword must be the last keyword, since it has a variable number of arguments. Each of the trailing arguments is a single LAMMPS command, and each command should be enclosed in quotes, so that the entire command will be treated as a single argument. This will also prevent any variables in the command from being evaluated until it is executed multiple times during the run. Note that if a command itself needs one of its arguments quoted (e.g. the "print"_print.html command), then you can use a combination of single and double quotes, as in the example above or below. The {every} keyword is a means to avoid listing a long series of runs and interleaving commands in your input script. For example, a "print"_print.html command could be invoked or a "fix"_fix.html could be redefined, e.g. to reset a thermostat temperature. Or this could be useful for invoking a command you have added to LAMMPS that wraps some other code (e.g. as a library) to perform a computation periodically during a long LAMMPS run. See "this section"_Section_modify.html of the documentation for info about how to add new commands to LAMMPS. See "this section"_Section_howto.html#howto_10 of the documentation for ideas about how to couple LAMMPS to other codes. With the {every} option, N total steps are simulated, in shorter runs of M steps each. After each M-length run, the specified commands are invoked. If only a single command is specified as NULL, then no command is invoked. Thus these lines: variable q equal x\[100\] run 6000 every 2000 "print 'Coord = $q'" :pre are the equivalent of: variable q equal x\[100\] run 2000 print "Coord = $q" run 2000 print "Coord = $q" run 2000 print "Coord = $q" :pre which does 3 runs of 2000 steps and prints the x-coordinate of a particular atom between runs. Note that the variable "$q" will be evaluated afresh each time the print command is executed. Note that by using the line continuation character "&", the run every command can be spread across many lines, though it is still a single command: run 100000 every 1000 & "print 'Minimum value = $a'" & "print 'Maximum value = $b'" & "print 'Temp = $c'" & "print 'Press = $d'" :pre If the {pre} and {post} options are set to "no" when used with the {every} keyword, then the 1st run will do the full setup and the last run will print the full timing summary, but these operations will be skipped for intermediate runs. NOTE: You might hope to specify a command that exits the run by jumping out of the loop, e.g. variable t equal temp run 10000 every 100 "if '$t < 300.0' then 'jump SELF afterrun'" :pre Unfortunately this will not currently work. The run command simply executes each command one at a time each time it pauses, then continues the run. You can replace the jump command with a simple "quit"_quit.html command and cause LAMMPS to exit during the middle of a run when the condition is met. [Restrictions:] When not using the {upto} keyword, the number of specified timesteps N must fit in a signed 32-bit integer, so you are limited to slightly more than 2 billion steps (2^31) in a single run. When using {upto}, N can be larger than a signed 32-bit integer, however the difference between N and the current timestep must still be no larger than 2^31 steps. However, with or without the {upto} keyword, you can perform successive runs to run a simulation for any number of steps (ok, up to 2^63 total steps). I.e. the timestep counter within LAMMPS is a 64-bit signed integer. [Related commands:] "minimize"_minimize.html, "run_style"_run_style.html, "temper"_temper.html [Default:] The option defaults are start = the current timestep, stop = current timestep + N, pre = yes, and post = yes. diff --git a/doc/src/run_style.txt b/doc/src/run_style.txt index 787ea6e1a..2dafabebb 100644 --- a/doc/src/run_style.txt +++ b/doc/src/run_style.txt @@ -1,294 +1,294 @@ "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 run_style command :h3 [Syntax:] run_style style args :pre style = {verlet} or {verlet/split} or {respa} or {respa/omp} :ulb,l {verlet} args = none {verlet/split} args = none {respa} args = N n1 n2 ... keyword values ... N = # of levels of rRESPA n1, n2, ... = loop factor between rRESPA levels (N-1 values) zero or more keyword/value pairings may be appended to the loop factors keyword = {bond} or {angle} or {dihedral} or {improper} or - {pair} or {inner} or {middle} or {outer} or {hybrid} or {kspace} + {pair} or {inner} or {middle} or {outer} or {hybrid} or {kspace} {bond} value = M M = which level (1-N) to compute bond forces in {angle} value = M M = which level (1-N) to compute angle forces in {dihedral} value = M M = which level (1-N) to compute dihedral forces in {improper} value = M M = which level (1-N) to compute improper forces in {pair} value = M M = which level (1-N) to compute pair forces in {inner} values = M cut1 cut2 M = which level (1-N) to compute pair inner forces in - cut1 = inner cutoff between pair inner and - pair middle or outer (distance units) - cut2 = outer cutoff between pair inner and - pair middle or outer (distance units) + cut1 = inner cutoff between pair inner and + pair middle or outer (distance units) + cut2 = outer cutoff between pair inner and + pair middle or outer (distance units) {middle} values = M cut1 cut2 M = which level (1-N) to compute pair middle forces in - cut1 = inner cutoff between pair middle and pair outer (distance units) - cut2 = outer cutoff between pair middle and pair outer (distance units) + cut1 = inner cutoff between pair middle and pair outer (distance units) + cut2 = outer cutoff between pair middle and pair outer (distance units) {outer} value = M M = which level (1-N) to compute pair outer forces in {hybrid} values = M1 M2 ... (as many values as there are hybrid sub-styles M1 = which level (1-N) to compute the first pair_style hybrid sub-style in M2 = which level (1-N) to compute the second pair_style hybrid sub-style in M3,etc {kspace} value = M M = which level (1-N) to compute kspace forces in :pre :ule [Examples:] run_style verlet run_style respa 4 2 2 2 bond 1 dihedral 2 pair 3 kspace 4 run_style respa 4 2 2 2 bond 1 dihedral 2 inner 3 5.0 6.0 outer 4 kspace 4 :pre run_style respa 3 4 2 bond 1 hybrid 2 2 1 kspace 3 :pre [Description:] Choose the style of time integrator used for molecular dynamics simulations performed by LAMMPS. The {verlet} style is a standard velocity-Verlet integrator. :line The {verlet/split} style is also a velocity-Verlet integrator, but it splits the force calculation within each timestep over 2 partitions of processors. See "Section 2.7"_Section_start.html#start_7 for an explanation of the -partition command-line switch. Specifically, this style performs all computation except the "kspace_style"_kspace_style.html portion of the force field on the 1st partition. This include the "pair style"_pair_style.html, "bond style"_bond_style.html, "neighbor list building"_neighbor.html, "fixes"_fix.html including time intergration, and output. The "kspace_style"_kspace_style.html portion of the calculation is performed on the 2nd partition. This is most useful for the PPPM kspace_style when its performance on a large number of processors degrades due to the cost of communication in its 3d FFTs. In this scenario, splitting your P total processors into 2 subsets of processors, P1 in the 1st partition and P2 in the 2nd partition, can enable your simulation to run faster. This is because the long-range forces in PPPM can be calculated at the same time as pair-wise and bonded forces are being calculated, and the FFTs can actually speed up when running on fewer processors. To use this style, you must define 2 partitions where P1 is a multiple of P2. Typically having P1 be 3x larger than P2 is a good choice. The 3d processor layouts in each partition must overlay in the following sense. If P1 is a Px1 by Py1 by Pz1 grid, and P2 = Px2 by Py2 by Pz2, then Px1 must be an integer multiple of Px2, and similarly for Py1 a multiple of Py2, and Pz1 a multiple of Pz2. Typically the best way to do this is to let the 1st partition choose its onn optimal layout, then require the 2nd partition's layout to match the integer multiple constraint. See the "processors"_processors.html command with its {part} keyword for a way to control this, e.g. procssors * * * part 1 2 multiple :pre You can also use the "partition"_partition.html command to explicitly specity the processor layout on each partition. E.g. for 2 partitions of 60 and 15 processors each: partition yes 1 processors 3 4 5 partition yes 2 processors 3 1 5 :pre When you run in 2-partition mode with the {verlet/split} style, the thermodyanmic data for the entire simulation will be output to the log and screen file of the 1st partition, which are log.lammps.0 and screen.0 by default; see the "-plog and -pscreen command-line switches"_Section_start.html#start_7 to change this. The log and screen file for the 2nd partition will not contain thermodynamic output beyone the 1st timestep of the run. See "Section 5"_Section_accelerate.html of the manual for performance details of the speed-up offered by the {verlet/split} style. One important performance consideration is the assignemnt of logical processors in the 2 partitions to the physical cores of a parallel machine. The "processors"_processors.html command has options to support this, and strategies are discussed in "Section 5"_Section_accelerate.html of the manual. :line The {respa} style implements the rRESPA multi-timescale integrator "(Tuckerman)"_#Tuckerman with N hierarchical levels, where level 1 is the innermost loop (shortest timestep) and level N is the outermost loop (largest timestep). The loop factor arguments specify what the looping factor is between levels. N1 specifies the number of iterations of level 1 for a single iteration of level 2, N2 is the iterations of level 2 per iteration of level 3, etc. N-1 looping parameters must be specified. The "timestep"_timestep.html command sets the timestep for the outermost rRESPA level. Thus if the example command above for a 4-level rRESPA had an outer timestep of 4.0 fmsec, the inner timestep would be 8x smaller or 0.5 fmsec. All other LAMMPS commands that specify number of timesteps (e.g. "neigh_modify"_neigh_modify.html parameters, "dump"_dump.html every N timesteps, etc) refer to the outermost timesteps. The rRESPA keywords enable you to specify at what level of the hierarchy various forces will be computed. If not specified, the defaults are that bond forces are computed at level 1 (innermost loop), angle forces are computed where bond forces are, dihedral forces are computed where angle forces are, improper forces are computed where dihedral forces are, pair forces are computed at the outermost level, and kspace forces are computed where pair forces are. The inner, middle, outer forces have no defaults. For fixes that support it, the rRESPA level at which a given fix is active, can be selected through the "fix_modify"_fix_modify.html command. The {inner} and {middle} keywords take additional arguments for cutoffs that are used by the pairwise force computations. If the 2 cutoffs for {inner} are 5.0 and 6.0, this means that all pairs up to 6.0 apart are computed by the inner force. Those between 5.0 and 6.0 have their force go ramped to 0.0 so the overlap with the next regime (middle or outer) is smooth. The next regime (middle or outer) will compute forces for all pairs from 5.0 outward, with those from 5.0 to 6.0 having their value ramped in an inverse manner. Only some pair potentials support the use of the {inner} and {middle} and {outer} keywords. If not, only the {pair} keyword can be used with that pair style, meaning all pairwise forces are computed at the same rRESPA level. See the doc pages for individual pair styles for details.i Another option for using pair potentials with rRESPA is with the {hybrid} keyword, which requires the use of the "pair_style hybrid or hybrid/overlay"_pair_hybrid.html command. In this scenario, different sub-styles of the hybrid pair style are evaluated at different rRESPA levels. This can be useful, for example, to set different timesteps for hybrid coarse-grained/all-atom models. The {hybrid} keyword requires as many level assignments as there are hybrid substyles, which assigns each sub-style to a rRESPA level, following their order of definition in the pair_style command. Since the {hybrid} keyword operates on pair style computations, it is mututally exclusive with either the {pair} or the {inner}/{middle}/{outer} keywords. When using rRESPA (or for any MD simulation) care must be taken to choose a timestep size(s) that insures the Hamiltonian for the chosen ensemble is conserved. For the constant NVE ensemble, total energy must be conserved. Unfortunately, it is difficult to know {a priori} how well energy will be conserved, and a fairly long test simulation (~10 ps) is usually necessary in order to verify that no long-term drift in energy occurs with the trial set of parameters. With that caveat, a few rules-of-thumb may be useful in selecting {respa} settings. The following applies mostly to biomolecular simulations using the CHARMM or a similar all-atom force field, but the concepts are adaptable to other problems. Without SHAKE, bonds involving hydrogen atoms exhibit high-frequency vibrations and require a timestep on the order of 0.5 fmsec in order to conserve energy. The relatively inexpensive force computations for the bonds, angles, impropers, and dihedrals can be computed on this innermost 0.5 fmsec step. The outermost timestep cannot be greater than 4.0 fmsec without risking energy drift. Smooth switching of forces between the levels of the rRESPA hierarchy is also necessary to avoid drift, and a 1-2 angstrom "healing distance" (the distance between the outer and inner cutoffs) works reasonably well. We thus recommend the following settings for use of the {respa} style without SHAKE in biomolecular simulations: timestep 4.0 run_style respa 4 2 2 2 inner 2 4.5 6.0 middle 3 8.0 10.0 outer 4 :pre With these settings, users can expect good energy conservation and roughly a 2.5 fold speedup over the {verlet} style with a 0.5 fmsec timestep. If SHAKE is used with the {respa} style, time reversibility is lost, but substantially longer time steps can be achieved. For biomolecular simulations using the CHARMM or similar all-atom force field, bonds involving hydrogen atoms exhibit high frequency vibrations and require a time step on the order of 0.5 fmsec in order to conserve energy. These high frequency modes also limit the outer time step sizes since the modes are coupled. It is therefore desirable to use SHAKE with respa in order to freeze out these high frequency motions and increase the size of the time steps in the respa hierarchy. The following settings can be used for biomolecular simulations with SHAKE and rRESPA: fix 2 all shake 0.000001 500 0 m 1.0 a 1 timestep 4.0 -run_style respa 2 2 inner 1 4.0 5.0 outer 2 :pre +run_style respa 2 2 inner 1 4.0 5.0 outer 2 :pre With these settings, users can expect good energy conservation and roughly a 1.5 fold speedup over the {verlet} style with SHAKE and a 2.0 fmsec timestep. For non-biomolecular simulations, the {respa} style can be advantageous if there is a clear separation of time scales - fast and slow modes in the simulation. Even a LJ system can benefit from rRESPA if the interactions are divided by the inner, middle and outer keywords. A 2-fold or more speedup can be obtained while maintaining good energy conservation. In real units, for a pure LJ fluid at liquid density, with a sigma of 3.0 angstroms, and epsilon of 0.1 Kcal/mol, the following settings seem to work well: timestep 36.0 run_style respa 3 3 4 inner 1 3.0 4.0 middle 2 6.0 7.0 outer 3 :pre :line The {respa/omp} styles is a variant of {respa} adapted for use with pair, bond, angle, dihedral, improper, or kspace styles with an {omp} suffix. It is functionally equivalent to {respa} but performs additional operations required for managing {omp} styles. For more on {omp} styles see the "Section 5"_Section_accelerate.html of the manual. Accelerated styles take the same arguments and should produce the same results, except for round-off and precision issues. You can specify {respa/omp} explicitly in your input script, or you can use the "-suffix command-line switch"_Section_start.html#start_7 when you invoke LAMMPS, or you can use the "suffix"_suffix.html command in your input script. See "Section 5"_Section_accelerate.html of the manual for more instructions on how to use the accelerated styles effectively. :line [Restrictions:] The {verlet/split} style can only be used if LAMMPS was built with the REPLICA package. Correspondingly the {respa/omp} style is available only if the USER-OMP package was included. See the "Making LAMMPS"_Section_start.html#start_3 section for more info on packages. Whenever using rRESPA, the user should experiment with trade-offs in speed and accuracy for their system, and verify that they are conserving energy to adequate precision. [Related commands:] "timestep"_timestep.html, "run"_run.html [Default:] run_style verlet :pre :line :link(Tuckerman) [(Tuckerman)] Tuckerman, Berne and Martyna, J Chem Phys, 97, p 1990 (1992). diff --git a/doc/src/set.txt b/doc/src/set.txt index c6fc16640..42ede23b8 100644 --- a/doc/src/set.txt +++ b/doc/src/set.txt @@ -1,434 +1,434 @@ "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 set command :h3 [Syntax:] set style ID keyword values ... :pre style = {atom} or {type} or {mol} or {group} or {region} :ulb,l ID = atom ID range or type range or mol ID range or group ID or region ID :l one or more keyword/value pairs may be appended :l keyword = {type} or {type/fraction} or {mol} or {x} or {y} or {z} or \ {charge} or {dipole} or {dipole/random} or {quat} or \ - {quat/random} or {diameter} or {shape} or \ - {length} or {tri} or {theta} or {theta/random} or \ + {quat/random} or {diameter} or {shape} or \ + {length} or {tri} or {theta} or {theta/random} or \ {angmom} or {omega} or \ - {mass} or {density} or {volume} or {image} or \ - {bond} or {angle} or {dihedral} or {improper} or \ - {meso/e} or {meso/cv} or {meso/rho} or \ - {smd/contact/radius} or {smd/mass/density} or {dpd/theta} or \ + {mass} or {density} or {volume} or {image} or \ + {bond} or {angle} or {dihedral} or {improper} or \ + {meso/e} or {meso/cv} or {meso/rho} or \ + {smd/contact/radius} or {smd/mass/density} or {dpd/theta} or \ {i_name} or {d_name} :l {type} value = atom type value can be an atom-style variable (see below) {type/fraction} values = type fraction seed type = new atom type fraction = fraction of selected atoms to set to new atom type seed = random # seed (positive integer) {mol} value = molecule ID value can be an atom-style variable (see below) {x},{y},{z} value = atom coordinate (distance units) value can be an atom-style variable (see below) {charge} value = atomic charge (charge units) value can be an atom-style variable (see below) {dipole} values = x y z x,y,z = orientation of dipole moment vector any of x,y,z can be an atom-style variable (see below) {dipole/random} value = seed Dlen seed = random # seed (positive integer) for dipole moment orientations Dlen = magnitude of dipole moment (dipole units) {quat} values = a b c theta a,b,c = unit vector to rotate particle around via right-hand rule theta = rotation angle (degrees) any of a,b,c,theta can be an atom-style variable (see below) {quat/random} value = seed seed = random # seed (positive integer) for quaternion orientations {diameter} value = diameter of spherical particle (distance units) value can be an atom-style variable (see below) {shape} value = Sx Sy Sz Sx,Sy,Sz = 3 diameters of ellipsoid (distance units) {length} value = len len = length of line segment (distance units) len can be an atom-style variable (see below) {tri} value = side side = side length of equilateral triangle (distance units) side can be an atom-style variable (see below) {theta} value = angle (degrees) angle = orientation of line segment with respect to x-axis angle can be an atom-style variable (see below) {theta/random} value = seed seed = random # seed (positive integer) for line segment orienations {angmom} values = Lx Ly Lz Lx,Ly,Lz = components of angular momentum vector (distance-mass-velocity units) any of Lx,Ly,Lz can be an atom-style variable (see below) {omega} values = Wx Wy Wz Wx,Wy,Wz = components of angular velocity vector (radians/time units) any of wx,wy,wz can be an atom-style variable (see below) {mass} value = per-atom mass (mass units) value can be an atom-style variable (see below) {density} value = particle density for sphere or ellipsoid (mass/distance^3 or mass/distance^2 or mass/distance units, depending on dimensionality of particle) value can be an atom-style variable (see below) {volume} value = particle volume for Peridynamic particle (distance^3 units) value can be an atom-style variable (see below) {image} nx ny nz nx,ny,nz = which periodic image of the simulation box the atom is in {bond} value = bond type for all bonds between selected atoms {angle} value = angle type for all angles between selected atoms {dihedral} value = dihedral type for all dihedrals between selected atoms {improper} value = improper type for all impropers between selected atoms {meso/e} value = energy of SPH particles (need units) value can be an atom-style variable (see below) {meso/cv} value = heat capacity of SPH particles (need units) value can be an atom-style variable (see below) {meso/rho} value = density of SPH particles (need units) value can be an atom-style variable (see below) {smd/contact/radius} = radius for short range interactions, i.e. contact and friction value can be an atom-style variable (see below) {smd/mass/density} = set particle mass based on volume by providing a mass density value can be an atom-style variable (see below) {dpd/theta} value = internal temperature of DPD particles (temperature units) value can be an atom-style variable (see below) value can be NULL which sets internal temp of each particle to KE temp {i_name} value = value for custom integer vector with name {d_name} value = value for custom floating-point vector with name :pre :ule [Examples:] set group solvent type 2 set group solvent type/fraction 2 0.5 12393 set group edge bond 4 set region half charge 0.5 set type 3 charge 0.5 set type 1*3 charge 0.5 set atom * charge v_atomfile set atom 100*200 x 0.5 y 1.0 set atom 1492 type 3 :pre [Description:] Set one or more properties of one or more atoms. Since atom properties are initially assigned by the "read_data"_read_data.html, "read_restart"_read_restart.html or "create_atoms"_create_atoms.html commands, this command changes those assignments. This can be useful for overriding the default values assigned by the "create_atoms"_create_atoms.html command (e.g. charge = 0.0). It can be useful for altering pairwise and molecular force interactions, since force-field coefficients are defined in terms of types. It can be used to change the labeling of atoms by atom type or molecule ID when they are output in "dump"_dump.html files. It can also be useful for debugging purposes; i.e. positioning an atom at a precise location to compute subsequent forces or energy. Note that the {style} and {ID} arguments determine which atoms have their properties reset. The remaining keywords specify which properties to reset and what the new values are. Some strings like {type} or {mol} can be used as a style and/or a keyword. :line This section describes how to select which atoms to change the properties of, via the {style} and {ID} arguments. The style {atom} selects all the atoms in a range of atom IDs. The style {type} selects all the atoms in a range of types. The style {mol} selects all the atoms in a range of molecule IDs. In each of the range cases, the range can be specified as a single numeric value, or a wildcard asterisk can be used to specify a range of values. This takes the form "*" or "*n" or "n*" or "m*n". For example, for the style {type}, if N = the number of atom types, then an asterisk with no numeric values means all types from 1 to N. A leading asterisk means all types from 1 to n (inclusive). A trailing asterisk means all types from n to N (inclusive). A middle asterisk means all types from m to n (inclusive). For all the styles except {mol}, the lowest value for the wildcard is 1; for {mol} it is 0. The style {group} selects all the atoms in the specified group. The style {region} selects all the atoms in the specified geometric region. See the "group"_group.html and "region"_region.html commands for details of how to specify a group or region. :line This section describes the keyword options for which properties to change, for the selected atoms. Note that except where explicitly prohibited below, all of the keywords allow an "atom-style or atomfile-style variable"_variable.html to be used as the specified value(s). If the value is a variable, it should be specified as v_name, where name is the variable name. In this case, the variable will be evaluated, and its resulting per-atom value used to determine the value assigned to each selected atom. Note that the per-atom value from the variable will be ignored for atoms that are not selected via the {style} and {ID} settings explained above. A simple way to use per-atom values from the variable to reset a property for all atoms is to use style {atom} with {ID} = "*"; this selects all atom IDs. Atom-style variables can specify formulas with various mathematical functions, and include "thermo_style"_thermo_style.html command keywords for the simulation box parameters and timestep and elapsed time. They can also include per-atom values, such as atom coordinates. Thus it is easy to specify a time-dependent or spatially-dependent set of per-atom values. As explained on the "variable"_variable.html doc page, atomfile-style variables can be used in place of atom-style variables, and thus as arguments to the set command. Atomfile-style variables read their per-atoms values from a file. NOTE: Atom-style and atomfile-style variables return floating point per-atom values. If the values are assigned to an integer variable, such as the molecule ID, then the floating point value is truncated to its integer portion, e.g. a value of 2.6 would become 2. Keyword {type} sets the atom type for all selected atoms. The specified value must be from 1 to ntypes, where ntypes was set by the "create_box"_create_box.html command or the {atom types} field in the header of the data file read by the "read_data"_read_data.html command. Keyword {type/fraction} sets the atom type for a fraction of the selected atoms. The actual number of atoms changed is not guaranteed to be exactly the requested fraction, but should be statistically close. Random numbers are used in such a way that a particular atom is changed or not changed, regardless of how many processors are being used. This keyword does not allow use of an atom-style variable. Keyword {mol} sets the molecule ID for all selected atoms. The "atom style"_atom_style.html being used must support the use of molecule IDs. Keywords {x}, {y}, {z}, and {charge} set the coordinates or charge of all selected atoms. For {charge}, the "atom style"_atom_style.html being used must support the use of atomic charge. Keyword {dipole} uses the specified x,y,z values as components of a vector to set as the orientation of the dipole moment vectors of the selected atoms. The magnitude of the dipole moment is set by the length of this orientation vector. Keyword {dipole/random} randomizes the orientation of the dipole moment vectors for the selected atoms and sets the magnitude of each to the specified {Dlen} value. For 2d systems, the z component of the orientation is set to 0.0. Random numbers are used in such a way that the orientation of a particular atom is the same, regardless of how many processors are being used. This keyword does not allow use of an atom-style variable. Keyword {quat} uses the specified values to create a quaternion (4-vector) that represents the orientation of the selected atoms. The particles must define a quaternion for their orientation (e.g. ellipsoids, triangles, body particles) as defined by the "atom_style"_atom_style.html command. Note that particles defined by "atom_style ellipsoid"_atom_style.html have 3 shape parameters. The 3 values must be non-zero for each particle set by this command. They are used to specify the aspect ratios of an ellipsoidal particle, which is oriented by default with its x-axis along the simulation box's x-axis, and similarly for y and z. If this body is rotated (via the right-hand rule) by an angle theta around a unit rotation vector (a,b,c), then the quaternion that represents its new orientation is given by (cos(theta/2), a*sin(theta/2), b*sin(theta/2), c*sin(theta/2)). The theta and a,b,c values are the arguments to the {quat} keyword. LAMMPS normalizes the quaternion in case (a,b,c) was not specified as a unit vector. For 2d systems, the a,b,c values are ignored, since a rotation vector of (0,0,1) is the only valid choice. Keyword {quat/random} randomizes the orientation of the quaternion for the selected atoms. The particles must define a quaternion for their orientation (e.g. ellipsoids, triangles, body particles) as defined by the "atom_style"_atom_style.html command. Random numbers are used in such a way that the orientation of a particular atom is the same, regardless of how many processors are being used. For 2d systems, only orientations in the xy plane are generated. As with keyword {quat}, for ellipsoidal particles, the 3 shape values must be non-zero for each particle set by this command. This keyword does not allow use of an atom-style variable. Keyword {diameter} sets the size of the selected atoms. The particles must be finite-size spheres as defined by the "atom_style sphere"_atom_style.html command. The diameter of a particle can be set to 0.0, which means they will be treated as point particles. Note that this command does not adjust the particle mass, even if it was defined with a density, e.g. via the "read_data"_read_data.html command. Keyword {shape} sets the size and shape of the selected atoms. The particles must be ellipsoids as defined by the "atom_style ellipsoid"_atom_style.html command. The {Sx}, {Sy}, {Sz} settings are the 3 diameters of the ellipsoid in each direction. All 3 can be set to the same value, which means the ellipsoid is effectively a sphere. They can also all be set to 0.0 which means the particle will be treated as a point particle. Note that this command does not adjust the particle mass, even if it was defined with a density, e.g. via the "read_data"_read_data.html command. Keyword {length} sets the length of selected atoms. The particles must be line segments as defined by the "atom_style line"_atom_style.html command. If the specified value is non-zero the line segment is (re)set to a length = the specified value, centered around the particle position, with an orientation along the x-axis. If the specified value is 0.0, the particle will become a point particle. Note that this command does not adjust the particle mass, even if it was defined with a density, e.g. via the "read_data"_read_data.html command. Keyword {tri} sets the size of selected atoms. The particles must be triangles as defined by the "atom_style tri"_atom_style.html command. If the specified value is non-zero the triangle is (re)set to be an equilateral triangle in the xy plane with side length = the specified value, with a centroid at the particle position, with its base parallel to the x axis, and the y-axis running from the center of the base to the top point of the triangle. If the specified value is 0.0, the particle will become a point particle. Note that this command does not adjust the particle mass, even if it was defined with a density, e.g. via the "read_data"_read_data.html command. Keyword {theta} sets the orientation of selected atoms. The particles must be line segments as defined by the "atom_style line"_atom_style.html command. The specified value is used to set the orientation angle of the line segments with respect to the x axis. Keyword {theta/random} randomizes the orientation of theta for the selected atoms. The particles must be line segments as defined by the "atom_style line"_atom_style.html command. Random numbers are used in such a way that the orientation of a particular atom is the same, regardless of how many processors are being used. This keyword does not allow use of an atom-style variable. Keyword {angmom} sets the angular momentum of selected atoms. The particles must be ellipsoids as defined by the "atom_style ellipsoid"_atom_style.html command or triangles as defined by the "atom_style tri"_atom_style.html command. The angular momentum vector of the particles is set to the 3 specified components. Keyword {omega} sets the angular velocity of selected atoms. The particles must be spheres as defined by the "atom_style sphere"_ atom_style.html command. The angular velocity vector of the particles is set to the 3 specified components. Keyword {mass} sets the mass of all selected particles. The particles must have a per-atom mass attribute, as defined by the "atom_style"_atom_style.html command. See the "mass" command for how to set mass values on a per-type basis. Keyword {density} also sets the mass of all selected particles, but in a different way. The particles must have a per-atom mass attribute, as defined by the "atom_style"_atom_style.html command. If the atom has a radius attribute (see "atom_style sphere"_atom_style.html) and its radius is non-zero, its mass is set from the density and particle volume. If the atom has a shape attribute (see "atom_style ellipsoid"_atom_style.html) and its 3 shape parameters are non-zero, then its mass is set from the density and particle volume. If the atom has a length attribute (see "atom_style line"_atom_style.html) and its length is non-zero, then its mass is set from the density and line segment length (the input density is assumed to be in mass/distance units). If the atom has an area attribute (see "atom_style tri"_atom_style.html) and its area is non-zero, then its mass is set from the density and triangle area (the input density is assumed to be in mass/distance^2 units). If none of these cases are valid, then the mass is set to the density value directly (the input density is assumed to be in mass units). Keyword {volume} sets the volume of all selected particles. Currently, only the "atom_style peri"_atom_style.html command defines particles with a volume attribute. Note that this command does not adjust the particle mass. Keyword {image} sets which image of the simulation box the atom is considered to be in. An image of 0 means it is inside the box as defined. A value of 2 means add 2 box lengths to get the true value. A value of -1 means subtract 1 box length to get the true value. LAMMPS updates these flags as atoms cross periodic boundaries during the simulation. The flags can be output with atom snapshots via the "dump"_dump.html command. If a value of NULL is specified for any of nx,ny,nz, then the current image value for that dimension is unchanged. For non-periodic dimensions only a value of 0 can be specified. This keyword does not allow use of atom-style variables. This command can be useful after a system has been equilibrated and atoms have diffused one or more box lengths in various directions. This command can then reset the image values for atoms so that they are effectively inside the simulation box, e.g if a diffusion coefficient is about to be measured via the "compute msd"_compute_msd.html command. Care should be taken not to reset the image flags of two atoms in a bond to the same value if the bond straddles a periodic boundary (rather they should be different by +/- 1). This will not affect the dynamics of a simulation, but may mess up analysis of the trajectories if a LAMMPS diagnostic or your own analysis relies on the image flags to unwrap a molecule which straddles the periodic box. Keywords {bond}, {angle}, {dihedral}, and {improper}, set the bond type (angle type, etc) of all bonds (angles, etc) of selected atoms to the specified value from 1 to nbondtypes (nangletypes, etc). All atoms in a particular bond (angle, etc) must be selected atoms in order for the change to be made. The value of nbondtype (nangletypes, etc) was set by the {bond types} ({angle types}, etc) field in the header of the data file read by the "read_data"_read_data.html command. These keywords do not allow use of an atom-style variable. Keywords {meso/e}, {meso/cv}, and {meso/rho} set the energy, heat capacity, and density of smmothed particle hydrodynamics (SPH) particles. See "this PDF guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in LAMMPS. Keyword {smd/mass/density} sets the mass of all selected particles, but it is only applicable to the Smooth Mach Dynamics package USER-SMD. It assumes that the particle volume has already been correctly set and calculates particle mass from the provided mass density value. Keyword {smd/contact/radius} only applies to simulations with the Smooth Mach Dynamics package USER-SMD. Itsets an interaction radius for computing short-range interactions, e.g. repulsive forces to prevent different individual physical bodies from penetrating each other. Note that the SPH smoothing kernel diameter used for computing long range, nonlocal interactions, is set using the {diameter} keyword. Keyword {dpd/theta} sets the internal temperature of a DPD particle as defined by the USER-DPD package. If the specified value is a number it must be >= 0.0. If the specified value is NULL, then the kinetic temperature Tkin of each particle is computed as 3/2 k Tkin = KE = 1/2 m v^2 = 1/2 m (vx*vx+vy*vy+vz*vz). Each particle's internal temperature is set to Tkin. If the specified value is an atom-style variable, then the variable is evaluated for each particle. If a value >= 0.0, the internal temperature is set to that value. If it is < 0.0, the computation of Tkin is performed and the internal temperature is set to that value. Keywords {i_name} and {d_name} refer to custom integer and floating-point properties that have been added to each atom via the "fix property/atom"_fix_property_atom.html command. When that command is used specific names are given to each attribute which are what is specified as the "name" portion of {i_name} or {d_name}. [Restrictions:] You cannot set an atom attribute (e.g. {mol} or {q} or {volume}) if the "atom_style"_atom_style.html does not have that attribute. This command requires inter-processor communication to coordinate the setting of bond types (angle types, etc). This means that your system must be ready to perform a simulation before using one of these keywords (force fields set, atom mass set, etc). This is not necessary for other keywords. Using the {region} style with the bond (angle, etc) keywords can give unpredictable results if there are bonds (angles, etc) that straddle periodic boundaries. This is because the region may only extend up to the boundary and partner atoms in the bond (angle, etc) may have coordinates outside the simulation box if they are ghost atoms. [Related commands:] "create_box"_create_box.html, "create_atoms"_create_atoms.html, "read_data"_read_data.html [Default:] none diff --git a/doc/src/thermo.txt b/doc/src/thermo.txt index 5001fb3c2..6faea206f 100644 --- a/doc/src/thermo.txt +++ b/doc/src/thermo.txt @@ -1,59 +1,59 @@ "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 thermo command :h3 [Syntax:] thermo N :pre N = output thermodynamics every N timesteps N can be a variable (see below) :ul [Examples:] thermo 100 :pre [Description:] Compute and print thermodynamic info (e.g. temperature, energy, pressure) on timesteps that are a multiple of N and at the beginning and end of a simulation. A value of 0 will only print thermodynamics at the beginning and end. The content and format of what is printed is controlled by the "thermo_style"_thermo_style.html and "thermo_modify"_thermo_modify.html commands. Instead of a numeric value, N can be specifed as an "equal-style variable"_variable.html, which should be specified as v_name, where name is the variable name. In this case, the variable is evaluated at the beginning of a run to determine the next timestep at which thermodynamic info will be written out. On that timestep, the variable will be evaluated again to determine the next timestep, etc. Thus the variable should return timestep values. See the stagger() and logfreq() and stride() math functions for "equal-style variables"_variable.html, as examples of useful functions to use in this context. Other similar math functions could easily be added as options for "equal-style variables"_variable.html. For example, the following commands will output thermodynamic info at timesteps 0,10,20,30,100,200,300,1000,2000,etc: -variable s equal logfreq(10,3,10) -thermo v_s :pre +variable s equal logfreq(10,3,10) +thermo v_s :pre [Restrictions:] none [Related commands:] "thermo_style"_thermo_style.html, "thermo_modify"_thermo_modify.html [Default:] thermo 0 :pre diff --git a/doc/src/thermo_style.txt b/doc/src/thermo_style.txt index 4c9811db6..5e662e85b 100644 --- a/doc/src/thermo_style.txt +++ b/doc/src/thermo_style.txt @@ -1,408 +1,408 @@ "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 thermo_style command :h3 [Syntax:] thermo_style style args :pre style = {one} or {multi} or {custom} :ulb,l args = list of arguments for a particular style :l {one} args = none {multi} args = none {custom} args = list of keywords possible keywords = step, elapsed, elaplong, dt, time, cpu, tpcpu, spcpu, cpuremain, part, timeremain, atoms, temp, press, pe, ke, etotal, enthalpy, evdwl, ecoul, epair, ebond, eangle, edihed, eimp, emol, elong, etail, vol, density, lx, ly, lz, xlo, xhi, ylo, yhi, zlo, zhi, - xy, xz, yz, xlat, ylat, zlat, + xy, xz, yz, xlat, ylat, zlat, bonds, angles, dihedrals, impropers, - pxx, pyy, pzz, pxy, pxz, pyz, - fmax, fnorm, nbuild, ndanger, - cella, cellb, cellc, cellalpha, cellbeta, cellgamma, - c_ID, c_ID\[I\], c_ID\[I\]\[J\], + pxx, pyy, pzz, pxy, pxz, pyz, + fmax, fnorm, nbuild, ndanger, + cella, cellb, cellc, cellalpha, cellbeta, cellgamma, + c_ID, c_ID\[I\], c_ID\[I\]\[J\], f_ID, f_ID\[I\], f_ID\[I\]\[J\], v_name, v_name\[I\] step = timestep elapsed = timesteps since start of this run elaplong = timesteps since start of initial run in a series of runs dt = timestep size time = simulation time cpu = elapsed CPU time in seconds tpcpu = time per CPU second spcpu = timesteps per CPU second cpuremain = estimated CPU time remaining in run part = which partition (0 to Npartition-1) this is timeremain = remaining time in seconds on timer timeout. atoms = # of atoms temp = temperature press = pressure pe = total potential energy ke = kinetic energy etotal = total energy (pe + ke) enthalpy = enthalpy (etotal + press*vol) evdwl = VanderWaal pairwise energy (includes etail) ecoul = Coulombic pairwise energy epair = pairwise energy (evdwl + ecoul + elong) ebond = bond energy eangle = angle energy edihed = dihedral energy eimp = improper energy emol = molecular energy (ebond + eangle + edihed + eimp) elong = long-range kspace energy etail = VanderWaal energy long-range tail correction vol = volume density = mass density of system lx,ly,lz = box lengths in x,y,z xlo,xhi,ylo,yhi,zlo,zhi = box boundaries xy,xz,yz = box tilt for triclinic (non-orthogonal) simulation boxes xlat,ylat,zlat = lattice spacings as calculated by "lattice"_lattice.html command bonds,angles,dihedrals,impropers = # of these interactions defined pxx,pyy,pzz,pxy,pxz,pyz = 6 components of pressure tensor fmax = max component of force on any atom in any dimension fnorm = length of force vector for all atoms nbuild = # of neighbor list builds ndanger = # of dangerous neighbor list builds cella,cellb,cellc = periodic cell lattice constants a,b,c cellalpha, cellbeta, cellgamma = periodic cell angles alpha,beta,gamma c_ID = global scalar value calculated by a compute with ID c_ID\[I\] = Ith component of global vector calculated by a compute with ID, I can include wildcard (see below) c_ID\[I\]\[J\] = I,J component of global array calculated by a compute with ID f_ID = global scalar value calculated by a fix with ID f_ID\[I\] = Ith component of global vector calculated by a fix with ID, I can include wildcard (see below) f_ID\[I\]\[J\] = I,J component of global array calculated by a fix with ID v_name = value calculated by an equal-style variable with name v_name\[I\] = value calculated by a vector-style variable with name :pre :ule [Examples:] thermo_style multi thermo_style custom step temp pe etotal press vol thermo_style custom step temp etotal c_myTemp v_abc thermo_style custom step temp etotal c_myTemp\[*\] v_abc :pre [Description:] Set the style and content for printing thermodynamic data to the screen and log file. Style {one} prints a one-line summary of thermodynamic info that is the equivalent of "thermo_style custom step temp epair emol etotal press". The line contains only numeric values. Style {multi} prints a multiple-line listing of thermodynamic info that is the equivalent of "thermo_style custom etotal ke temp pe ebond eangle edihed eimp evdwl ecoul elong press". The listing contains numeric values and a string ID for each quantity. Style {custom} is the most general setting and allows you to specify which of the keywords listed above you want printed on each thermodynamic timestep. Note that the keywords c_ID, f_ID, v_name are references to "computes"_compute.html, "fixes"_fix.html, and equal-style "variables"_variable.html" that have been defined elsewhere in the input script or can even be new styles which users have added to LAMMPS (see the "Section 10"_Section_modify.html section of the documentation). Thus the {custom} style provides a flexible means of outputting essentially any desired quantity as a simulation proceeds. All styles except {custom} have {vol} appended to their list of outputs if the simulation box volume changes during the simulation. The values printed by the various keywords are instantaneous values, calculated on the current timestep. Time-averaged quantities, which include values from previous timesteps, can be output by using the f_ID keyword and accessing a fix that does time-averaging such as the "fix ave/time"_fix_ave_time.html command. Options invoked by the "thermo_modify"_thermo_modify.html command can be used to set the one- or multi-line format of the print-out, the normalization of thermodynamic output (total values versus per-atom values for extensive quantities (ones which scale with the number of atoms in the system), and the numeric precision of each printed value. NOTE: When you use a "thermo_style" command, all thermodynamic settings are restored to their default values, including those previously set by a "thermo_modify"_thermo_modify.html command. Thus if your input script specifies a thermo_style command, you should use the thermo_modify command after it. :line Several of the thermodynamic quantities require a temperature to be computed: "temp", "press", "ke", "etotal", "enthalpy", "pxx", etc. By default this is done by using a {temperature} compute which is created when LAMMPS starts up, as if this command had been issued: compute thermo_temp all temp :pre See the "compute temp"_compute_temp.html command for details. Note that the ID of this compute is {thermo_temp} and the group is {all}. You can change the attributes of this temperature (e.g. its degrees-of-freedom) via the "compute_modify"_compute_modify.html command. Alternatively, you can directly assign a new compute (that calculates temperature) which you have defined, to be used for calculating any thermodynamic quantity that requires a temperature. This is done via the "thermo_modify"_thermo_modify.html command. Several of the thermodynamic quantities require a pressure to be computed: "press", "enthalpy", "pxx", etc. By default this is done by using a {pressure} compute which is created when LAMMPS starts up, as if this command had been issued: compute thermo_press all pressure thermo_temp :pre See the "compute pressure"_compute_pressure.html command for details. Note that the ID of this compute is {thermo_press} and the group is {all}. You can change the attributes of this pressure via the "compute_modify"_compute_modify.html command. Alternatively, you can directly assign a new compute (that calculates pressure) which you have defined, to be used for calculating any thermodynamic quantity that requires a pressure. This is done via the "thermo_modify"_thermo_modify.html command. Several of the thermodynamic quantities require a potential energy to be computed: "pe", "etotal", "ebond", etc. This is done by using a {pe} compute which is created when LAMMPS starts up, as if this command had been issued: compute thermo_pe all pe :pre See the "compute pe"_compute_pe.html command for details. Note that the ID of this compute is {thermo_pe} and the group is {all}. You can change the attributes of this potential energy via the "compute_modify"_compute_modify.html command. :line The kinetic energy of the system {ke} is inferred from the temperature of the system with 1/2 Kb T of energy for each degree of freedom. Thus, using different "compute commands"_compute.html for calculating temperature, via the "thermo_modify temp"_thermo_modify.html command, may yield different kinetic energies, since different computes that calculate temperature can subtract out different non-thermal components of velocity and/or include different degrees of freedom (translational, rotational, etc). The potential energy of the system {pe} will include contributions from fixes if the "fix_modify thermo"_fix_modify.html option is set for a fix that calculates such a contribution. For example, the "fix wall/lj93"_fix_wall.html fix calculates the energy of atoms interacting with the wall. See the doc pages for "individual fixes" to see which ones contribute. A long-range tail correction {etail} for the VanderWaal pairwise energy will be non-zero only if the "pair_modify tail"_pair_modify.html option is turned on. The {etail} contribution is included in {evdwl}, {epair}, {pe}, and {etotal}, and the corresponding tail correction to the pressure is included in {press} and {pxx}, {pyy}, etc. :line The {step}, {elapsed}, and {elaplong} keywords refer to timestep count. {Step} is the current timestep, or iteration count when a "minimization"_minimize.html is being performed. {Elapsed} is the number of timesteps elapsed since the beginning of this run. {Elaplong} is the number of timesteps elapsed since the beginning of an initial run in a series of runs. See the {start} and {stop} keywords for the "run"_run.html for info on how to invoke a series of runs that keep track of an initial starting time. If these keywords are not used, then {elapsed} and {elaplong} are the same value. The {dt} keyword is the current timestep size in time "units"_units.html. The {time} keyword is the current elapsed simulation time, also in time "units"_units.html, which is simply (step*dt) if the timestep size has not changed and the timestep has not been reset. If the timestep has changed (e.g. via "fix dt/reset"_fix_dt_reset.html) or the timestep has been reset (e.g. via the "reset_timestep" command), then the simulation time is effectively a cummulative value up to the current point. The {cpu} keyword is elapsed CPU seconds since the beginning of this run. The {tpcpu} and {spcpu} keywords are measures of how fast your simulation is currently running. The {tpcpu} keyword is simulation time per CPU second, where simulation time is in time "units"_units.html. E.g. for metal units, the {tpcpu} value would be picoseconds per CPU second. The {spcpu} keyword is the number of timesteps per CPU second. Both quantities are on-the-fly metrics, measured relative to the last time they were invoked. Thus if you are printing out thermodyamic output every 100 timesteps, the two keywords will continually output the time and timestep rate for the last 100 steps. The {tpcpu} keyword does not attempt to track any changes in timestep size, e.g. due to using the "fix dt/reset"_fix_dt_reset.html command. The {cpuremain} keyword estimates the CPU time remaining in the current run, based on the time elapsed thus far. It will only be a good estimate if the CPU time/timestep for the rest of the run is similar to the preceding timesteps. On the initial timestep the value will be 0.0 since there is no history to estimate from. For a minimization run performed by the "minimize" command, the estimate is based on the {maxiter} parameter, assuming the minimization will proceed for the maximum number of allowed iterations. The {part} keyword is useful for multi-replica or multi-partition simulations to indicate which partition this output and this file corresponds to, or for use in a "variable"_variable.html to append to a filename for output specific to this partition. See "Section 2.7"_Section_start.html#start_7 of the manual for details on running in multi-partition mode. The {timeremain} keyword returns the remaining seconds when a timeout has been configured via the "timer timeout"_timer.html command. If the timeout timer is inactive, the value of this keyword is 0.0 and if the timer is expired, it is negative. This allows for example to exit loops cleanly, if the timeout is expired with: if "$(timeremain) < 0.0" then "quit 0" :pre The {fmax} and {fnorm} keywords are useful for monitoring the progress of an "energy minimization"_minimize.html. The {fmax} keyword calculates the maximum force in any dimension on any atom in the system, or the infinity-norm of the force vector for the system. The {fnorm} keyword calculates the 2-norm or length of the force vector. The {nbuild} and {ndanger} keywords are useful for monitoring neighbor list builds during a run. Note that both these values are also printed with the end-of-run statistics. The {nbuild} keyword is the number of re-builds during the current run. The {ndanger} keyword is the number of re-builds that LAMMPS considered potentially "dangerous". If atom movement triggered neighbor list rebuilding (see the "neigh_modify"_neigh_modify.html command), then dangerous reneighborings are those that were triggered on the first timestep atom movement was checked for. If this count is non-zero you may wish to reduce the delay factor to insure no force interactions are missed by atoms moving beyond the neighbor skin distance before a rebuild takes place. The keywords {cella}, {cellb}, {cellc}, {cellalpha}, {cellbeta}, {cellgamma}, correspond to the usual crystallographic quantities that define the periodic unit cell of a crystal. See "this section"_Section_howto.html#howto_12 of the doc pages for a geometric description of triclinic periodic cells, including a precise defintion of these quantities in terms of the internal LAMMPS cell dimensions {lx}, {ly}, {lz}, {yz}, {xz}, {xy}. :line For output values from a compute or fix, the bracketed index I used to index a vector, as in {c_ID\[I\]} or {f_ID\[I\]}, can be specified using a wildcard asterisk with the index to effectively specify multiple values. This takes the form "*" or "*n" or "n*" or "m*n". If N = the size of the vector (for {mode} = scalar) or the number of columns in the array (for {mode} = vector), then an asterisk with no numeric values means all indices from 1 to N. A leading asterisk means all indices from 1 to n (inclusive). A trailing asterisk means all indices from n to N (inclusive). A middle asterisk means all indices from m to n (inclusive). Using a wildcard is the same as if the individual elements of the vector had been listed one by one. E.g. these 2 thermo_style commands are equivalent, since the "compute temp"_compute_temp.html command creates a global vector with 6 values. compute myTemp all temp thermo_style custom step temp etotal c_myTemp\[*\] thermo_style custom step temp etotal & c_myTemp\[1\] c_myTemp\[2\] c_myTemp\[3\] & c_myTemp\[4\] c_myTemp\[5\] c_myTemp\[6\] :pre :line The {c_ID} and {c_ID\[I\]} and {c_ID\[I\]\[J\]} keywords allow global values calculated by a compute to be output. As discussed on the "compute"_compute.html doc page, computes can calculate global, per-atom, or local values. Only global values can be referenced by this command. However, per-atom compute values for an individual atom can be referenced in a "variable"_variable.html and the variable referenced by thermo_style custom, as discussed below. See the discussion above for how the I in {c_ID\[I\]} can be specified with a wildcard asterisk to effectively specify multiple values from a global compute vector. The ID in the keyword should be replaced by the actual ID of a compute that has been defined elsewhere in the input script. See the "compute"_compute.html command for details. If the compute calculates a global scalar, vector, or array, then the keyword formats with 0, 1, or 2 brackets will reference a scalar value from the compute. Note that some computes calculate "intensive" global quantities like temperature; others calculate "extensive" global quantities like kinetic energy that are summed over all atoms in the compute group. Intensive quantities are printed directly without normalization by thermo_style custom. Extensive quantities may be normalized by the total number of atoms in the simulation (NOT the number of atoms in the compute group) when output, depending on the "thermo_modify norm"_thermo_modify.html option being used. The {f_ID} and {f_ID\[I\]} and {f_ID\[I\]\[J\]} keywords allow global values calculated by a fix to be output. As discussed on the "fix"_fix.html doc page, fixes can calculate global, per-atom, or local values. Only global values can be referenced by this command. However, per-atom fix values can be referenced for an individual atom in a "variable"_variable.html and the variable referenced by thermo_style custom, as discussed below. See the discussion above for how the I in {f_ID\[I\]} can be specified with a wildcard asterisk to effectively specify multiple values from a global fix vector. The ID in the keyword should be replaced by the actual ID of a fix that has been defined elsewhere in the input script. See the "fix"_fix.html command for details. If the fix calculates a global scalar, vector, or array, then the keyword formats with 0, 1, or 2 brackets will reference a scalar value from the fix. Note that some fixes calculate "intensive" global quantities like timestep size; others calculate "extensive" global quantities like energy that are summed over all atoms in the fix group. Intensive quantities are printed directly without normalization by thermo_style custom. Extensive quantities may be normalized by the total number of atoms in the simulation (NOT the number of atoms in the fix group) when output, depending on the "thermo_modify norm"_thermo_modify.html option being used. The {v_name} keyword allow the current value of a variable to be output. The name in the keyword should be replaced by the variable name that has been defined elsewhere in the input script. Only equal-style and vector-style variables can be referenced; the latter requires a bracketed term to specify the Ith element of the vector calculated by the variable. However, an atom-style variable can be referenced for an individual atom by an equal-style variable and that variable referenced. See the "variable"_variable.html command for details. Variables of style {equal} and {vector} and {atom} define a formula which can reference per-atom properties or thermodynamic keywords, or they can invoke other computes, fixes, or variables when evaluated, so this is a very general means of creating thermodynamic output. Note that equal-style and vector-style variables are assumed to produce "intensive" global quantities, which are thus printed as-is, without normalization by thermo_style custom. You can include a division by "natoms" in the variable formula if this is not the case. :line [Restrictions:] This command must come after the simulation box is defined by a "read_data"_read_data.html, "read_restart"_read_restart.html, or "create_box"_create_box.html command. [Related commands:] "thermo"_thermo.html, "thermo_modify"_thermo_modify.html, "fix_modify"_fix_modify.html, "compute temp"_compute_temp.html, "compute pressure"_compute_pressure.html [Default:] thermo_style one :pre diff --git a/doc/src/variable.txt b/doc/src/variable.txt index 876c6bd4a..29d50a2b8 100644 --- a/doc/src/variable.txt +++ b/doc/src/variable.txt @@ -1,1325 +1,1325 @@ "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 variable command :h3 [Syntax:] 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 {python} or {internal} or {equal} or {vector} or {atom} :l {delete} = no args {index} args = one or more strings {loop} args = N N = integer size of loop, loop from 1 to N inclusive {loop} args = N pad N = integer size of loop, loop from 1 to N inclusive pad = all values will be same length, e.g. 001, 002, ..., 100 {loop} args = N1 N2 N1,N2 = loop from N1 to N2 inclusive {loop} args = N1 N2 pad N1,N2 = loop from N1 to N2 inclusive pad = all values will be same length, e.g. 050, 051, ..., 100 {world} args = one string for each partition of processors {universe} args = one or more strings {uloop} args = N N = integer size of loop {uloop} args = N pad N = integer size of loop pad = all values will be same length, e.g. 001, 002, ..., 100 {string} arg = one string {format} args = vname fstr vname = name of equal-style variable to evaluate fstr = C-style format string {getenv} arg = one string {file} arg = filename {atomfile} arg = filename {python} arg = function {internal} arg = numeric value {equal} or {vector} 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, version, on, off, true, false, yes, no thermo keywords = vol, ke, press, etc from "thermo_style"_thermo_style.html math operators = (), -x, x+y, x-y, x*y, x/y, x^y, x%y, x == y, x != y, x < y, x <= y, x > y, x >= y, x && y, x || y, x |^ y, !x math functions = sqrt(x), exp(x), ln(x), log(x), abs(x), sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y,x), random(x,y,z), normal(x,y,z), ceil(x), floor(x), round(x) ramp(x,y), stagger(x,y), logfreq(x,y,z), logfreq2(x,y,z), - stride(x,y,z), stride2(x,y,z,a,b,c), - vdisplace(x,y), swiggle(x,y,z), cwiggle(x,y,z) + stride(x,y,z), stride2(x,y,z,a,b,c), + vdisplace(x,y), swiggle(x,y,z), cwiggle(x,y,z) group functions = count(group), mass(group), charge(group), - xcm(group,dim), vcm(group,dim), fcm(group,dim), - bound(group,dir), gyration(group), ke(group), - angmom(group,dim), torque(group,dim), + xcm(group,dim), vcm(group,dim), fcm(group,dim), + bound(group,dir), gyration(group), ke(group), + angmom(group,dim), torque(group,dim), inertia(group,dimdim), omega(group,dim) region functions = count(group,region), mass(group,region), charge(group,region), - xcm(group,dim,region), vcm(group,dim,region), fcm(group,dim,region), - bound(group,dir,region), gyration(group,region), ke(group,reigon), - angmom(group,dim,region), torque(group,dim,region), - inertia(group,dimdim,region), omega(group,dim,region) + xcm(group,dim,region), vcm(group,dim,region), fcm(group,dim,region), + bound(group,dir,region), gyration(group,region), ke(group,reigon), + angmom(group,dim,region), torque(group,dim,region), + inertia(group,dimdim,region), omega(group,dim,region) special functions = sum(x), min(x), max(x), ave(x), trap(x), slope(x), gmask(x), rmask(x), grmask(x,y), next(x) feature functions = is_active(category,feature,exact), is_defined(category,id,exact) atom value = id\[i\], mass\[i\], type\[i\], mol\[i\], x\[i\], y\[i\], z\[i\], vx\[i\], vy\[i\], vz\[i\], fx\[i\], fy\[i\], fz\[i\], q\[i\] atom vector = id, mass, type, mol, x, y, z, vx, vy, vz, fx, fy, fz, q compute references = c_ID, c_ID\[i\], c_ID\[i\]\[j\], C_ID, C_ID\[i\] fix references = f_ID, f_ID\[i\], f_ID\[i\]\[j\], F_ID, F_ID\[i\] variable references = v_name, v_name\[i\] :pre :ule [Examples:] variable x index run1 run2 run3 run4 run5 run6 run7 run8 variable LoopVar loop $n variable beta equal temp/3.0 variable b1 equal x\[234\]+0.5*vol variable b1 equal "x\[234\] + 0.5*vol" variable b equal xcm(mol1,x)/2.0 variable b equal c_myTemp variable b atom x*y/vol variable foo string myfile variable foo internal 3.5 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 variable x uloop 15 pad variable str format x %.6g variable x delete :pre [Description:] This command assigns one or more strings to a variable name for evaluation later in the input script or during a simulation. Variables can thus be useful in several contexts. A variable can be defined and then referenced elsewhere in an input script to become part of a new input command. For variable styles that store multiple strings, the "next"_next.html command can be used to increment which string is assigned to the variable. Variables of style {equal} store a formula which when evaluated produces a single numeric value which can be output either directly (see the "print"_print.html, "fix print"_fix_print.html, and "run every"_run.html commands) or as part of thermodynamic output (see the "thermo_style"_thermo_style.html command), or used as input to an averaging fix (see the "fix ave/time"_fix_ave_time.html command). Variables of style {vector} store a formula which produces a vector of such values which can be used as input to various averaging fixes, or elements of which can be part of thermodynamic output. Variables of style {atom} store a formula which when evaluated produces one numeric value per atom which can be output to a dump file (see the "dump custom"_dump.html command) or used as input to an averaging fix (see the "fix ave/chunk"_fix_ave_chunk.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. Variables of style {python} can be hooked to Python functions using code you provide, so that the variable gets its value from the evaluation of the Python code. Variables of style {internal} are used by a few commands which set their value directly. NOTE: As discussed in "Section 3.2"_Section_commands.html#cmd_2 of the manual, an input script can use "immediate" variables, specified as $(formula) with parenthesis, where the formula has the same syntax as equal-style variables described on this page. This is a convenient way to evaluate a formula immediately without using the variable command to define a named variable and then evaluate that variable. See below for a more detailed discussion of this feature. In the discussion that follows, the "name" of the variable is the arbitrary string that is the 1st argument in the variable command. This name can only contain alphanumeric characters and underscores. The "string" is one or more of the subsequent arguments. The "string" can be simple text as in the 1st example above, it can contain other variables as in the 2nd example, or it can be a formula as in the 3rd example. The "value" is the numeric quantity resulting from evaluation of the string. Note that the same string can generate different values when it is evaluated at different times during a simulation. NOTE: When an input script line is encountered that defines a variable of style {equal} or {vector} or {atom} or {python} that contains a formula or Python code, the formula is NOT immediately evaluated. It will be evaluated every time when the variable is [used] instead. If you simply want to evaluate a formula in place you can use as so-called. See the section below about "Immediate Evaluation of Variables" for more details on the topic. This is also true of a {format} style variable since it evaluates another variable when it is invoked. Variables of style {equal} and {vector} and {atom} can be used as inputs to various other commands which evaluate their formulas as needed, e.g. at different timesteps during a "run"_run.html. Variables of style {internal} can be used in place of an equal-style variable, except by commands that set the value stored by the internal-style variable. Thus any command that states it can use an equal-style variable as an argument, can also use an internal-style variable. This means that when the command evaluates the variable, it will use the value set (internally) by another command. 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. NOTE: When a variable command is encountered in the input script and the variable name has already been specified, the command is ignored. This means variables can NOT be re-defined in an input script (with two exceptions, read further). This is to allow an input script to be processed multiple times without resetting the variables; see the "jump"_jump.html or "include"_include.html commands. It also means that using the "command-line switch"_Section_start.html#start_7 -var will override a corresponding index variable setting in the input script. There are two exceptions to this rule. First, variables of style {string}, {getenv}, {internal}, {equal}, {vector}, {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 from the list of active variables, and is thus available to be re-defined in a subsequent variable command. The {delete} style does the same thing. :line "This section"_Section_commands.html#cmd_2 of the manual explains how occurrences of a variable name in an input script line are replaced by the variable's string. The variable name can be referenced as $x if the name "x" is a single character, or as $\{LoopVar\} if the name "LoopVar" is one or more characters. As described below, for variable styles {index}, {loop}, {file}, {universe}, and {uloop}, which string is assigned to a variable can be incremented via the "next"_next.html command. When there are no more strings to assign, the variable is exhausted and a flag is set that causes the next "jump"_jump.html command encountered in the input script to be skipped. This enables the construction of simple loops in the input script that are iterated over and then exited from. As explained above, an exhausted variable can be re-used in an input script. The {delete} style also removes the variable, the same as if it were exhausted, allowing it to be redefined later in the input script or when the input script is looped over. This can be useful when breaking out of a loop via the "if"_if.html and "jump"_jump.html commands before the variable would become exhausted. For example, -label loop +label loop variable a loop 5 -print "A = $a" -if "$a > 2" then "jump in.script break" -next a -jump in.script loop -label break +print "A = $a" +if "$a > 2" then "jump in.script break" +next a +jump in.script loop +label break variable a delete :pre :line This section describes how all the various variable styles are defined and what they store. Except for the {equal} and {vector} and {atom} styles, which are explained 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 "next"_next.html command is used with the variable name, the next string is assigned. All processors assign the same string to the variable. {Index} style variables with a single string value can also be set by using the command-line switch -var; see "this section"_Section_start.html#start_7 for details. The {loop} style is identical to the {index} style except that the strings are the integers from 1 to N inclusive, if only one argument N is specified. This allows generation of a long list of runs (e.g. 1000) without having to list N strings in the input script. Initially, the string "1" is assigned to the variable. Each time a "next"_next.html command is used with the variable name, the next string ("2", "3", etc) is assigned. All processors assign the same string to the variable. The {loop} style can also be specified with two arguments N1 and N2. In this case the loop runs from N1 to N2 inclusive, and the string N1 is initially assigned to the variable. N1 <= N2 and N2 >= 0 is required. For the {world} style, one or more strings are specified. There must be one string for each processor partition or "world". See "this section"_Section_start.html#start_7 of the manual for information on running LAMMPS with multiple partitions via the "-partition" command-line switch. This variable command assigns one string to each world. All processors in the world are assigned the same string. The next command cannot be used with {equal} style variables, since there is only one value per world. This style of variable is useful when you wish to run different simulations on different partitions, or when performing a parallel tempering simulation (see the "temper"_temper.html command), to assign different temperatures to different partitions. For the {universe} style, one or more strings are specified. There must be at least as many strings as there are processor partitions or "worlds". See "this page"_Section_start.html#start_7 for information on running LAMMPS with multiple partitions via the "-partition" command-line switch. This variable command initially assigns one string to each world. When a "next"_next.html command is encountered using this variable, the first processor partition to encounter it, is assigned the next available string. This continues until all the variable strings are consumed. Thus, this command can be used to run 50 simulations on 8 processor partitions. The simulations will be run one after the other on whatever partition becomes available, until they are all finished. {Universe} style variables are incremented using the files "tmp.lammps.variable" and "tmp.lammps.variable.lock" which you will see in your directory during such a LAMMPS run. The {uloop} style is identical to the {universe} style except that the strings are the integers from 1 to N. This allows generation of long list of runs (e.g. 1000) without having to list N strings in the input script. For the {string} style, a single string is assigned to the variable. The only difference between this and using the {index} style with a single string is that a variable with {string} style can be redefined. E.g. by another command later in the input script, or if the script is read again in a loop. For the {format} style, an equal-style variable is specified along with a C-style format string, e.g. "%f" or "%.10g", which must be appropriate for formatting a double-precision floating-point value. This allows an equal-style variable to be formatted specifically for output as a string, e.g. by the "print"_print.html command, if the default format "%.15g" has too much precision. For the {getenv} style, a single string is assigned to the variable which should be the name of an environment variable. When the variable is evaluated, it returns the value of the environment variable, or an empty string if it not defined. This style of variable can be used to adapt the behavior of LAMMPS input scripts via environment variable settings, or to retrieve information that has been previously stored with the "shell putenv"_shell.html command. Note that because environment variable settings are stored by the operating systems, they persist beyond a "clear"_clear.html command. For the {file} style, a filename is provided which contains a list of strings to assign to the variable, one per line. The strings can be numeric values if desired. See the discussion of the next() function below for equal-style variables, which will convert the string of a file-style variable into a numeric value in a formula. When a file-style variable is defined, the file is opened and the string on the first line is read and stored with the variable. This means the variable can then be evaluated as many times as desired and will return that string. There are two ways to cause the next string from the file to be read: use the "next"_next.html command or the next() function in an equal- or atom-style variable, as discussed below. The rules for formatting the file are as follows. A comment character "#" can be used anywhere on a line; text starting with the comment character is stripped. Blank lines are skipped. The first "word" of a non-blank line, delimited by white space, is the "string" assigned to the variable. For the {atomfile} style, a filename is provided which contains one or more sets of values, to assign on a per-atom basis to the variable. The format of the file is described below. When an atomfile-style variable is defined, the file is opened and the first set of per-atom values are read and stored with the variable. This means the variable can then be evaluated as many times as desired and will return those values. There are two ways to cause the next set of per-atom values from the file to be read: use the "next"_next.html command or the next() function in an atom-style variable, as discussed below. The rules for formatting the file are as follows. Each time a set of per-atom values is read, a non-blank line is searched for in the file. A comment character "#" can be used anywhere on a line; text starting with the comment character is stripped. Blank lines are skipped. The first "word" of a non-blank line, delimited by white space, is read as the count N of per-atom lines to immediately follow. N can be be the total number of atoms in the system, or only a subset. The next N lines have the following format ID value :pre where ID is an atom ID and value is the per-atom numeric value that will be assigned to that atom. IDs can be listed in any order. 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 example 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. For the {internal} style a numeric value is provided. This value will be assigned to the variable until a LAMMPS command sets it to a new value. There are currently only two LAMMPS commands that require {internal} variables as inputs, because they reset them: "create_atoms"_create_atoms.html and "fix controller"_fix_controller.html. As mentioned above, an internal-style variable can be used in place of an equal-style variable anywhere else in an input script, e.g. as an argument to another command that allows for equal-style variables. :line For the {equal} and {vector} and {atom} styles, a single string is specified which represents a formula that will be evaluated afresh each time the variable is used. If you want spaces in the string, enclose it in double quotes so the parser will treat it as a single argument. For {equal}-style variables the formula computes a scalar quantity, which becomes the value of the variable whenever it is evaluated. For {vector}-style variables the formula must compute a vector of quantities, which becomes the value of the variable whenever it is evaluated. The calculated vector can be on length one, but it cannot be a simple scalar value like that produced by an equal-style compute. I.e. the formula for a vector-style variable must have at least one quantity in it that refers to a global vector produced by a compute, fix, or other vector-style variable. For {atom}-style variables the formula computes one quantity for each atom whenever it is evaluated. Note that {equal}, {vector}, and {atom} variables can produce different values at different stages of the input script or at different times during a run. For example, if an {equal} variable is used in a "fix print"_fix_print.html command, different values could be printed each timestep it was invoked. If you want a variable to be evaluated immediately, so that the result is stored by the variable instead of the string, see the section below on "Immediate Evaluation of Variables". The next command cannot be used with {equal} or {vector} or {atom} style variables, since there is only one string. The formula for an {equal}, {vector}, or {atom} variable can contain a variety of quantities. The syntax for each kind of quantity is simple, but multiple quantities can be nested and combined in various ways to build up formulas of arbitrary complexity. For example, this is a valid (though strange) variable formula: variable x equal "pe + c_MyTemp / vol^(1/3)" :pre Specifically, a formula can contain numbers, constants, thermo keywords, math operators, math functions, group functions, region functions, atom values, atom vectors, compute references, fix references, and references to other variables. Number: 0.2, 100, 1.0e20, -15.4, etc Constant: PI, version, on, off, true, false, yes, no Thermo keywords: vol, pe, ebond, etc Math operators: (), -x, x+y, x-y, x*y, x/y, x^y, x%y, \ x == y, x != y, x < y, x <= y, x > y, x >= y, x && y, x || y, x |^ y, !x Math functions: sqrt(x), exp(x), ln(x), log(x), abs(x), \ sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y,x), \ random(x,y,z), normal(x,y,z), ceil(x), floor(x), round(x), \ ramp(x,y), stagger(x,y), logfreq(x,y,z), logfreq2(x,y,z), \ stride(x,y,z), stride2(x,y,z,a,b,c), vdisplace(x,y), \ swiggle(x,y,z), cwiggle(x,y,z) Group functions: count(ID), mass(ID), charge(ID), xcm(ID,dim), \ vcm(ID,dim), fcm(ID,dim), bound(ID,dir), \ gyration(ID), ke(ID), angmom(ID,dim), torque(ID,dim), \ inertia(ID,dimdim), omega(ID,dim) Region functions: count(ID,IDR), mass(ID,IDR), charge(ID,IDR), \ xcm(ID,dim,IDR), vcm(ID,dim,IDR), fcm(ID,dim,IDR), \ bound(ID,dir,IDR), gyration(ID,IDR), ke(ID,IDR), \ angmom(ID,dim,IDR), torque(ID,dim,IDR), \ inertia(ID,dimdim,IDR), omega(ID,dim,IDR) Special functions: sum(x), min(x), max(x), ave(x), trap(x), \ slope(x), gmask(x), rmask(x), grmask(x,y), next(x) Atom values: id\[i\], mass\[i\], type\[i\], mol\[i\], x\[i\], y\[i\], z\[i\], \ vx\[i\], vy\[i\], vz\[i\], fx\[i\], fy\[i\], fz\[i\], q\[i\] Atom vectors: id, mass, type, mol, x, y, z, vx, vy, vz, fx, fy, fz, q Compute references: c_ID, c_ID\[i\], c_ID\[i\]\[j\], C_ID, C_ID\[i\] Fix references: f_ID, f_ID\[i\], f_ID\[i\]\[j\], F_ID, F_ID\[i\] Other variables: v_name, v_name\[i\] :tb(s=:) Most of the formula elements produce a scalar value. Some produce a global or per-atom vector of values. Global vectors can be produced by computes or fixes or by other vector-style variables. Per-atom vectors are produced by atom vectors, compute references that represent a per-atom vector, fix references that represent a per-atom vector, and variables that are atom-style variables. Math functions that operate on scalar values produce a scalar value; math function that operate on global or per-atom vectors do so element-by-element and produce a global or per-atom vector. A formula for equal-style variables cannot use any formula element that produces a global or per-atom vector. A formula for a vector-style variable can use formula elements that produce either a scalar value or a global vector value, but cannot use a formula element that produces a per-atom vector. A formula for an atom-style variable can use formula elements that produce either a scalar value or a per-atom vector, but not one that produces a global vector. Atom-style variables are evaluated by other commands that define a "group"_group.html on which they operate, e.g. a "dump"_dump.html or "compute"_compute.html or "fix"_fix.html command. When they invoke the atom-style variable, only atoms in the group are included in the formula evaluation. The variable evaluates to 0.0 for atoms not in the group. :line Numers, constants, and thermo keywords :h4 Numbers can contain digits, scientific notation (3.0e20,3.0e-20,3.0E20,3.0E-20), and leading minus signs. Constants are set at compile time and cannot be changed. {PI} will return the number 3.14159265358979323846; {on}, {true} or {yes} will return 1.0; {off}, {false} or {no} will return 0.0; {version} will return a numeric version code of the current LAMMPS version (e.g. version 2 Sep 2015 will return the number 20150902). The corresponding value for newer versions of LAMMPS will be larger, for older versions of LAMMPS will be smaller. This can be used to have input scripts adapt automatically to LAMMPS versions, when non-backwards compatible syntax changes are introduced. Here is an illustrative example (which will not work, since the {version} has been introduced more recently): if $(version<20140513) then "communicate vel yes" else "comm_modify vel yes" :pre The thermo keywords allowed in a formula are those defined by the "thermo_style custom"_thermo_style.html command. Thermo keywords that require a "compute"_compute.html to calculate their values such as "temp" or "press", use computes stored and invoked by the "thermo_style"_thermo_style.html command. This means that you can only use those keywords in a variable if the style you are using with the thermo_style command (and the thermo keywords associated with that style) also define and use the needed compute. Note that some thermo keywords use a compute indirectly to calculate their value (e.g. the enthalpy keyword uses temp, pe, and pressure). If a variable is evaluated directly in an input script (not during a run), then the values accessed by the thermo keyword must be current. See the discussion below about "Variable Accuracy". :line Math Operators :h4 Math operators are written in the usual way, where the "x" and "y" in the examples can themselves be arbitrarily complex formulas, as in the examples above. In this syntax, "x" and "y" can be scalar values or per-atom vectors. For example, "ke/natoms" is the division of two scalars, where "vy+vz" is the element-by-element sum of two per-atom vectors of y and z velocities. Operators are evaluated left to right and have the usual C-style precedence: unary minus and unary logical NOT operator "!" have the highest precedence, exponentiation "^" is next; multiplication and division and the modulo operator "%" are next; addition and subtraction are next; the 4 relational operators "<", "<=", ">", and ">=" are next; the two remaining relational operators "==" and "!=" are next; then the logical AND operator "&&"; and finally the logical OR operator "||" and logical XOR (exclusive or) operator "|^" have the lowest precedence. Parenthesis can be used to group one or more portions of a formula and/or enforce a different order of evaluation than what would occur with the default precedence. NOTE: Because a unary minus is higher precedence than exponentiation, the formula "-2^2" will evaluate to 4, not -4. This convention is compatible with some programming languages, but not others. As mentioned, this behavior can be easily overridden with parenthesis; the formula "-(2^2)" will evaluate to -4. The 6 relational operators return either a 1.0 or 0.0 depending on whether the relationship between x and y is TRUE or FALSE. For example the expression x<10.0 in an atom-style variable formula will return 1.0 for all atoms whose x-coordinate is less than 10.0, and 0.0 for the others. The logical AND operator will return 1.0 if both its arguments are non-zero, else it returns 0.0. The logical OR operator will return 1.0 if either of its arguments is non-zero, else it returns 0.0. The logical XOR operator will return 1.0 if one of its arguments is zero and the other non-zero, else it returns 0.0. The logical NOT operator returns 1.0 if its argument is 0.0, else it returns 0.0. These relational and logical operators can be used as a masking or selection operation in a formula. For example, the number of atoms whose properties satifsy one or more criteria could be calculated by taking the returned per-atom vector of ones and zeroes and passing it to the "compute reduce"_compute_reduce.html command. :line Math Functions :h4 Math functions are specified as keywords followed by one or more parenthesized arguments "x", "y", "z", each of which can themselves be arbitrarily complex formulas. In this syntax, the arguments can represent scalar values or global vectors or per-atom vectors. In the latter case, the math operation is performed on each element of the vector. For example, "sqrt(natoms)" is the sqrt() of a scalar, where "sqrt(y*z)" yields a per-atom vector with each element being the sqrt() of the product of one atom's y and z coordinates. Most of the math functions perform obvious operations. The ln() is the natural log; log() is the base 10 log. The random(x,y,z) function takes 3 arguments: x = lo, y = hi, and z = seed. It generates a uniform random number between lo and hi. The normal(x,y,z) function also takes 3 arguments: x = mu, y = sigma, and z = seed. It generates a Gaussian variate centered on mu with variance sigma^2. In both cases the seed is used the first time the internal random number generator is invoked, to initialize it. For equal-style and vector-style variables, every processor uses the same seed so that they each generate the same sequence of random numbers. For atom-style variables, a unique seed is created for each processor, based on the specified seed. This effectively generates a different random number for each atom being looped over in the atom-style variable. NOTE: Internally, there is just one random number generator for all equal-style and vector-style variables and another one for all atom-style variables. If you define multiple variables (of each style) which use the random() or normal() math functions, then the internal random number generators will only be initialized once, which means only one of the specified seeds will determine the sequence of generated random numbers. The ceil(), floor(), and round() functions are those in the C math library. Ceil() is the smallest integer not less than its argument. Floor() if the largest integer not greater than its argument. Round() is the nearest integer to its argument. The ramp(x,y) function uses the current timestep to generate a value linearly intepolated between the specified x,y values over the course of a run, according to this formula: value = x + (y-x) * (timestep-startstep) / (stopstep-startstep) :pre The run begins on startstep and ends on stopstep. Startstep and stopstep can span multiple runs, using the {start} and {stop} keywords of the "run"_run.html command. See the "run"_run.html command for details of how to do this. The stagger(x,y) function uses the current timestep to generate a new timestep. X,y > 0 and x > y are required. The generated timesteps increase in a staggered fashion, as the sequence x,x+y,2x,2x+y,3x,3x+y,etc. For any current timestep, the next timestep in the sequence is returned. Thus if stagger(1000,100) is used in a variable by the "dump_modify every"_dump_modify.html command, it will generate the sequence of output timesteps: 100,1000,1100,2000,2100,3000,etc :pre The logfreq(x,y,z) function uses the current timestep to generate a new timestep. X,y,z > 0 and y < z are required. The generated timesteps are on a base-z logarithmic scale, starting with x, and the y value is how many of the z-1 possible timesteps within one logarithmic interval are generated. I.e. the timesteps follow the sequence x,2x,3x,...y*x,x*z,2x*z,3x*z,...y*x*z,x*z^2,2x*z^2,etc. For any current timestep, the next timestep in the sequence is returned. Thus if logfreq(100,4,10) is used in a variable by the "dump_modify every"_dump_modify.html command, it will generate this sequence of output timesteps: 100,200,300,400,1000,2000,3000,4000,10000,20000,etc :pre The logfreq2(x,y,z) function is similar to logfreq, except a single logarithmic interval is divided into y equally-spaced timesteps and all of them are output. Y < z is not required. Thus, if logfreq2(100,18,10) is used in a variable by the "dump_modify every"_dump_modify.html command, then the interval between 100 and 1000 is divided as 900/18 = 50 steps, and it will generate the sequence of output timesteps: 100,150,200,...950,1000,1500,2000,...9500,10000,15000,etc :pre The stride(x,y,z) function uses the current timestep to generate a new timestep. X,y >= 0 and z > 0 and x <= y are required. The generated timesteps increase in increments of z, from x to y, i.e. it generates the sequece x,x+z,x+2z,...,y. If y-x is not a multiple of z, then similar to the way a for loop operates, the last value will be one that does not exceed y. For any current timestep, the next timestep in the sequence is returned. Thus if stride(1000,2000,100) is used in a variable by the "dump_modify every"_dump_modify.html command, it will generate the sequence of output timesteps: 1000,1100,1200, ... ,1900,2000 :pre The stride2(x,y,z,a,b,c) function is similar to the stride() function except it generates two sets of strided timesteps, one at a coarser level and one at a finer level. Thus it is useful for debugging, e.g. to produce output every timestep at the point in simulation when a problem occurs. X,y >= 0 and z > 0 and x <= y are required, as are a,b >= 0 and c > 0 and a < b. Also, a >= x and b <= y are required so that the second stride is inside the first. The generated timesteps increase in increments of z, starting at x, until a is reached. At that point the timestep increases in increments of c, from a to b, then after b, increments by z are resumed until y is reached. For any current timestep, the next timestep in the sequence is returned. Thus if stride(1000,2000,100,1350,1360,1) is used in a variable by the "dump_modify every"_dump_modify.html command, it will generate the sequence of output timesteps: 1000,1100,1200,1300,1350,1351,1352, ... 1359,1360,1400,1500, ... ,2000 :pre The vdisplace(x,y) function takes 2 arguments: x = value0 and y = velocity, and uses the elapsed time to change the value by a linear displacement due to the applied velocity over the course of a run, according to this formula: value = value0 + velocity*(timestep-startstep)*dt :pre where dt = the timestep size. The run begins on startstep. Startstep can span multiple runs, using the {start} keyword of the "run"_run.html command. See the "run"_run.html command for details of how to do this. Note that the "thermo_style"_thermo_style.html keyword elaplong = timestep-startstep. The swiggle(x,y,z) and cwiggle(x,y,z) functions each take 3 arguments: x = value0, y = amplitude, z = period. They use the elapsed time to oscillate the value by a sin() or cos() function over the course of a run, according to one of these formulas, where omega = 2 PI / period: value = value0 + Amplitude * sin(omega*(timestep-startstep)*dt) value = value0 + Amplitude * (1 - cos(omega*(timestep-startstep)*dt)) :pre where dt = the timestep size. The run begins on startstep. Startstep can span multiple runs, using the {start} keyword of the "run"_run.html command. See the "run"_run.html command for details of how to do this. Note that the "thermo_style"_thermo_style.html keyword elaplong = timestep-startstep. :line Group and Region Functions :h4 Group functions are specified as keywords followed by one or two parenthesized arguments. The first argument {ID} is the group-ID. The {dim} argument, if it exists, is {x} or {y} or {z}. The {dir} argument, if it exists, is {xmin}, {xmax}, {ymin}, {ymax}, {zmin}, or {zmax}. The {dimdim} argument, if it exists, is {xx} or {yy} or {zz} or {xy} or {yz} or {xz}. The group function count() is the number of atoms in the group. The group functions mass() and charge() are the total mass and charge of the group. Xcm() and vcm() return components of the position and velocity of the center of mass of the group. Fcm() returns a component of the total force on the group of atoms. Bound() returns the min/max of a particular coordinate for all atoms in the group. Gyration() computes the radius-of-gyration of the group of atoms. See the "compute gyration"_compute_gyration.html command for a definition of the formula. Angmom() returns components of the angular momentum of the group of atoms around its center of mass. Torque() returns components of the torque on the group of atoms around its center of mass, based on current forces on the atoms. Inertia() returns one of 6 components of the symmetric inertia tensor of the group of atoms around its center of mass, ordered as Ixx,Iyy,Izz,Ixy,Iyz,Ixz. Omega() returns components of the angular velocity of the group of atoms around its center of mass. Region functions are specified exactly the same way as group functions except they take an extra final argument {IDR} which is the region ID. The function is computed for all atoms that are in both the group and the region. If the group is "all", then the only criteria for atom inclusion is that it be in the region. :line Special Functions :h4 Special functions take specific kinds of arguments, meaning their arguments cannot be formulas themselves. The sum(x), min(x), max(x), ave(x), trap(x), and slope(x) functions each take 1 argument which is of the form "c_ID" or "c_ID\[N\]" or "f_ID" or "f_ID\[N\]" or "v_name". The first two are computes and the second two are fixes; the ID in the reference should be replaced by the ID of a compute or fix defined elsewhere in the input script. The compute or fix must produce either a global vector or array. If it produces a global vector, then the notation without "\[N\]" should be used. If it produces a global array, then the notation with "\[N\]" should be used, when N is an integer, to specify which column of the global array is being referenced. The last form of argument "v_name" is for a vector-style variable where "name" is replaced by the name of the variable. These functions operate on a global vector of inputs and reduce it to a single scalar value. This is analagous to the operation of the "compute reduce"_compute_reduce.html command, which performs similar operations on per-atom and local vectors. The sum() function calculates the sum of all the vector elements. The min() and max() functions find the minimum and maximum element respectively. The ave() function is the same as sum() except that it divides the result by the length of the vector. The trap() function is the same as sum() except the first and last elements are multiplied by a weighting factor of 1/2 when performing the sum. This effectively implements an integration via the trapezoidal rule on the global vector of data. I.e. consider a set of points, equally spaced by 1 in their x coordinate: (1,V1), (2,V2), ..., (N,VN), where the Vi are the values in the global vector of length N. The integral from 1 to N of these points is trap(). When appropriately normalized by the timestep size, this function is useful for calculating integrals of time-series data, like that generated by the "fix ave/correlate"_fix_ave_correlate.html command. The slope() function uses linear regression to fit a line to the set of points, equally spaced by 1 in their x coordinate: (1,V1), (2,V2), ..., (N,VN), where the Vi are the values in the global vector of length N. The returned value is the slope of the line. If the line has a single point or is vertical, it returns 1.0e20. The gmask(x) function takes 1 argument which is a group ID. It can only be used in atom-style variables. It returns a 1 for atoms that are in the group, and a 0 for atoms that are not. The rmask(x) function takes 1 argument which is a region ID. It can only be used in atom-style variables. It returns a 1 for atoms that are in the geometric region, and a 0 for atoms that are not. The grmask(x,y) function takes 2 arguments. The first is a group ID, and the second is a region ID. It can only be used in atom-style variables. It returns a 1 for atoms that are in both the group and region, and a 0 for atoms that are not in both. The next(x) function takes 1 argument which is a variable ID (not "v_foo", just "foo"). It must be for a file-style or atomfile-style variable. Each time the next() function is invoked (i.e. each time the equal-style or atom-style variable is evaluated), the following steps occur. For file-style variables, the current string value stored by the file-style variable is converted to a numeric value and returned by the function. And the next string value in the file is read and stored. Note that if the line previously read from the file was not a numeric string, then it will typically evaluate to 0.0, which is likely not what you want. For atomfile-style variables, the current per-atom values stored by the atomfile-style variable are returned by the function. And the next set of per-atom values in the file is read and stored. Since file-style and atomfile-style variables read and store the first line of the file or first set of per-atoms values when they are defined in the input script, these are the value(s) that will be returned the first time the next() function is invoked. If next() is invoked more times than there are lines or sets of lines in the file, the variable is deleted, similar to how the "next"_next.html command operates. :line Feature Functions :h4 Feature functions allow to probe the running LAMMPS executable for whether specific features are either active, defined, or available. The functions take two arguments, a {category} and a corresponding {argument}. The arguments are strings thus cannot be formulas themselves (only $-style immediate variable expansion is possible). Return value is either 1.0 or 0.0 depending on whether the function evaluates to true or false, respectively. The {is_active()} function allows to query for active settings which are grouped by categories. Currently supported categories and arguments are: {package} (argument = {cuda} or {gpu} or {intel} or {kokkos} or {omp}) {newton} (argument = {pair} or {bond} or {any}) {pair} (argument = {single} or {respa} or {manybody} or {tail} or {shift}) {comm_style} (argument = {brick} or {tiled}) {min_style} (argument = any of the compiled in minimizer styles) {run_style} (argument = any of the compiled in run styles) {atom_style} (argument = any of the compiled in atom styles) {pair_style} (argument = any of the compiled in pair styles) {bond_style} (argument = any of the compiled in bond styles) {angle_style} (argument = any of the compiled in angle styles) {dihedral_style} (argument = any of the compiled in dihedral styles) {improper_style} (argument = any of the compiled in improper styles) {kspace_style} (argument = any of the compiled in kspace styles) :ul Most of the settings are self-explanatory, the {single} argument in the {pair} category allows to check whether a pair style supports a Pair::single() function as needed by compute group/group and others features or LAMMPS, {respa} allows to check whether the inner/middle/outer mode of r-RESPA is supported. In the various style categories, the checking is also done using suffix flags, if available and enabled. Example 1: disable use of suffix for pppm when using GPU package (i.e. run it on the CPU concurrently to running the pair style on the GPU), but do use the suffix otherwise (e.g. with USER-OMP). pair_style lj/cut/coul/long 14.0 if $(is_active(package,gpu)) then "suffix off" kspace_style pppm :pre Example 2: use r-RESPA with inner/outer cutoff, if supported by pair style, otherwise fall back to using pair and reducing the outer time step timestep $(2.0*(1.0+*is_active(pair,respa)) if $(is_active(pair,respa)) then "run_style respa 4 3 2 2 improper 1 inner 2 5.5 7.0 outer 3 kspace 4" else "run_style respa 3 3 2 improper 1 pair 2 kspace 3" :pre The {is_defined()} function allows to query categories like {compute}, {dump}, {fix}, {group}, {region}, and {variable} whether an entry with the provided name or id is defined. The {is_available(category,name)} function allows to query whether a specific optional feature is available, i.e. compiled in. This currently works for the following categories: {command}, {compute}, {fix}, {pair_style} and {feature}. For all categories except {command} and {feature} also appending active suffixes is tried before reporting failure. The {feature} category is used to check the availability of compiled in features such as GZIP support, PNG support, JPEG support, FFMPEG support, and C++ exceptions for error handling. Corresponding values for name are {gzip}, {png}, {jpeg}, {ffmpeg} and {exceptions}. This enables writing input scripts which only dump using a given format if the compiled binary supports it. if "$(is_available(feature,png))" then "print 'PNG supported'" else "print 'PNG not supported'" :pre if "$(is_available(feature,ffmpeg)" then "dump 3 all movie 25 movie.mp4 type type zoom 1.6 adiam 1.0" :pre :line Atom Values and Vectors :h4 Atom values take an integer argument I from 1 to N, where I is the atom-ID, e.g. x\[243\], which means use the x coordinate of the atom with ID = 243. Or they can take a variable name, specified as v_name, where name is the name of the variable, like x\[v_myIndex\]. The variable can be of any style except {vector} or {atom} or {atomfile} variables. The variable is evaluated and the result is expected to be numeric and is cast to an integer (i.e. 3.4 becomes 3), to use an an index, which must be a value from 1 to N. Note that a "formula" cannot be used as the argument between the brackets, e.g. x\[243+10\] or x\[v_myIndex+1\] are not allowed. To do this a single variable can be defined that contains the needed formula. Note that the 0 < atom-ID <= N, where N is the largest atom ID in the system. If an ID is specified for an atom that does not currently exist, then the generated value is 0.0. Atom vectors generate one value per atom, so that a reference like "vx" means the x-component of each atom's velocity will be used when evaluating the variable. The meaning of the different atom values and vectors is mostly self-explanatory. {Mol} refers to the molecule ID of an atom, and is only defined if an "atom_style"_atom_style.html is being used that defines molecule IDs. Note that many other atom attributes can be used as inputs to a variable by using the "compute property/atom"_compute_property_atom.html command and then specifying a quantity from that compute. :line Compute References :h4 Compute references access quantities calculated by a "compute"_compute.html. The ID in the reference should be replaced by the ID of a compute defined elsewhere in the input script. As discussed in the doc page for the "compute"_compute.html command, computes can produce global, per-atom, or local values. Only global and per-atom values can be used in a variable. Computes can also produce a scalar, vector, or array. An equal-style variable can only use scalar values, which means a global scalar, or an element of a global or per-atom vector or array. A vector-style variable can use scalar values or a global vector of values, or a column of a global array of values. Atom-style variables can use global scalar values. They can also use per-atom vector values, or a column of a per-atom array. See the doc pages for individual computes to see what kind of values they produce. Examples of different kinds of compute references are as follows. There is typically no ambiguity (see exception below) as to what a reference means, since computes only produce either global or per-atom quantities, never both. c_ID: global scalar, or per-atom vector c_ID\[I\]: Ith element of global vector, or atom I's value in per-atom vector, or Ith column from per-atom array c_ID\[I\]\[J\]: I,J element of global array, or atom I's Jth value in per-atom array :tb(s=:) For I and J indices, integers can be specified or a variable name, specified as v_name, where name is the name of the variable. The rules for this syntax are the same as for the "Atom Values and Vectors" discussion above. One source of ambiguity for compute references is when a vector-style variable refers to a compute that produces both a global scalar and a global vector. Consider a compute with ID "foo" that does this, referenced as follows by variable "a", where "myVec" is another vector-style variable: variable a vector c_foo*v_myVec :pre The reference "c_foo" could refer to either the global scalar or global vector produced by compute "foo". In this case, "c_foo" will always refer to the global scalar, and "C_foo" can be used to reference the global vector. Similarly if the compute produces both a global vector and global array, then "c_foo\[I\]" will always refer to an element of the global vector, and "C_foo\[I\]" can be used to reference the Ith column of the global array. Note that if a variable containing a compute is evaluated directly in an input script (not during a run), then the values accessed by the compute must be current. See the discussion below about "Variable Accuracy". :line Fix References :h4 Fix references access quantities calculated by a "fix"_compute.html. The ID in the reference should be replaced by the ID of a fix defined elsewhere in the input script. As discussed in the doc page for the "fix"_fix.html command, fixes can produce global, per-atom, or local values. Only global and per-atom values can be used in a variable. Fixes can also produce a scalar, vector, or array. An equal-style variable can only use scalar values, which means a global scalar, or an element of a global or per-atom vector or array. Atom-style variables can use the same scalar values. They can also use per-atom vector values. A vector value can be a per-atom vector itself, or a column of an per-atom array. See the doc pages for individual fixes to see what kind of values they produce. The different kinds of fix references are exactly the same as the compute references listed in the above table, where "c_" is replaced by "f_". Again, there is typically no ambiguity (see exception below) as to what a reference means, since fixes only produce either global or per-atom quantities, never both. f_ID: global scalar, or per-atom vector f_ID\[I\]: Ith element of global vector, or atom I's value in per-atom vector, or Ith column from per-atom array f_ID\[I\]\[J\]: I,J element of global array, or atom I's Jth value in per-atom array :tb(s=:) For I and J indices, integers can be specified or a variable name, specified as v_name, where name is the name of the variable. The rules for this syntax are the same as for the "Atom Values and Vectors" discussion above. One source of ambiguity for fix references is the same ambiguity discussed for compute references above. Namely when a vector-style variable refers to a fix that produces both a global scalar and a global vector. The solution is the same as for compute references. For a fix with ID "foo", "f_foo" will always refer to the global scalar, and "F_foo" can be used to reference the global vector. And similarly for distinguishing between a fix's global vector versus global array with "f_foo\[I\]" versus "F_foo\[I\]". Note that if a variable containing a fix is evaluated directly in an input script (not during a run), then the values accessed by the fix should be current. See the discussion below about "Variable Accuracy". Note that some fixes only generate quantities on certain timesteps. If a variable attempts to access the fix on non-allowed timesteps, an error is generated. For example, the "fix ave/time"_fix_ave_time.html command may only generate averaged quantities every 100 steps. See the doc pages for individual fix commands for details. :line Variable References :h4 Variable references access quantities stored or calculated by other variables, which will cause those variables to be evaluated. The name in the reference should be replaced by the name of a variable defined elsewhere in the input script. As discussed on this doc page, equal-style variables generate a single global numeric value, vector-style variables gerarate a vector of global numeric values, and atom-style and atomfile-style variables generate a per-atom vector of numeric values. All other variables store one or more strings. The formula for an equal-style variable can use any style of variable including a vector_style or atom-style or atomfile-style. For these 3 styles, a subscript must be used to access a single value from the vector-, atom-, or atomfile-style variable. If a string-storing variable is used, the string is converted to a numeric value. Note that this will typically produce a 0.0 if the string is not a numeric string, which is likely not what you want. The formula for a vector-style variable can use any style of variable, including atom-style or atomfile-style variables. For these 2 styles, a subscript must be used to access a single value from the atom-, or atomfile-style variable. The formula for an atom-style variable can use any style of variable, including other atom-style or atomfile-style variables. If it uses a vector-style variable, a subscript must be used to access a single value from the vector-style variable. Examples of different kinds of variable references are as follows. There is no ambiguity as to what a reference means, since variables produce only a global scalar or global vector or per-atom vector. v_name: global scalar from equal-style variable v_name: global vector from vector-style variable v_name: per-atom vector from atom-style or atomfile-style variable v_name\[I\]: Ith element of a global vector from vector-style variable v_name\[I\]: value of atom with ID = I from atom-style or atomfile-style variable :tb(s=:) For the I index, an integer can be specified or a variable name, specified as v_name, where name is the name of the variable. The rules for this syntax are the same as for the "Atom Values and Vectors" discussion above. :line [Immediate Evaluation of Variables:] If you want an equal-style variable to be evaluated immediately, it may be the case that you do not need to define a variable at all. See "Section 3.2"_Section_commands.html#cmd_2 of the manual, which describes the use of "immediate" variables in an input script, specified as $(formula) with parenthesis, where the formula has the same syntax as equal-style variables described on this page. This effectively evaluates a formula immediately without using the variable command to define a named variable. More generally, there is a difference between referencing a variable with a leading $ sign (e.g. $x or $\{abc\}) versus with a leading "v_" (e.g. v_x or v_abc). The former can be used in any input script command, including a variable command. The input script parser evaluates the reference variable immediately and substitutes its value into the command. As explained in "Section 3.2"_Section_commands.html#cmd_2 for "Parsing rules", you can also use un-named "immediate" variables for this purpose. For example, a string like this $((xlo+xhi)/2+sqrt(v_area)) in an input script command evaluates the string between the parenthesis as an equal-style variable formula. Referencing a variable with a leading "v_" is an optional or required kind of argument for some commands (e.g. the "fix ave/chunk"_fix_ave_chunk.html or "dump custom"_dump.html or "thermo_style"_thermo_style.html commands) if you wish it to evaluate a variable periodically during a run. It can also be used in a variable formula if you wish to reference a second variable. The second variable will be evaluated whenever the first variable is evaluated. As an example, suppose you use this command in your input script to define the variable "v" as variable v equal vol :pre before a run where the simulation box size changes. You might think this will assign the initial volume to the variable "v". That is not the case. Rather it assigns a formula which evaluates the volume (using the thermo_style keyword "vol") to the variable "v". If you use the variable "v" in some other command like "fix ave/time"_fix_ave_time.html then the current volume of the box will be evaluated continuously during the run. If you want to store the initial volume of the system, you can do it this way: variable v equal vol variable v0 equal $v :pre The second command will force "v" to be evaluated (yielding the initial volume) and assign that value to the variable "v0". Thus the command thermo_style custom step v_v v_v0 :pre would print out both the current and initial volume periodically during the run. Note that it is a mistake to enclose a variable formula in double quotes if it contains variables preceeded by $ signs. For example, variable vratio equal "$\{vfinal\}/$\{v0\}" :pre This is because the quotes prevent variable substitution (see "this section"_Section_commands.html#cmd_2 on parsing input script commands), and thus an error will occur when the formula for "vratio" is evaluated later. :line [Variable Accuracy:] Obviously, LAMMPS attempts to evaluate variables containing formulas ({equal} and {atom} style variables) accurately whenever the evaluation is performed. Depending on what is included in the formula, this may require invoking a "compute"_compute.html, either directly or indirectly via a thermo keyword, or accessing a value previously calculated by a compute, or accessing a value calculated and stored by a "fix"_fix.html. If the compute is one that calculates the pressure or energy of the system, then these quantities need to be tallied during the evaluation of the interatomic potentials (pair, bond, etc) on timesteps that the variable will need the values. LAMMPS keeps track of all of this during a "run"_run.html or "energy minimization"_minimize.html. An error will be generated if you attempt to evaluate a variable on timesteps when it cannot produce accurate values. For example, if a "thermo_style custom"_thermo_style.html command prints a variable which accesses values stored by a "fix ave/time"_fix_ave_time.html command and the timesteps on which thermo output is generated are not multiples of the averaging frequency used in the fix command, then an error will occur. An input script can also request variables be evaluated before or after or in between runs, e.g. by including them in a "print"_print.html command. In this case, if a compute is needed to evaluate a variable (either directly or indirectly), LAMMPS will not invoke the compute, but it will use a value previously calculated by the compute, and can do this only if it was invoked on the current timestep. Fixes will always provide a quantity needed by a variable, but the quantity may or may not be current. This leads to one of three kinds of behavior: (1) The variable may be evaluated accurately. If it contains references to a compute or fix, and these values were calculated on the last timestep of a preceeding run, then they will be accessed and used by the variable and the result will be accurate. (2) LAMMPS may not be able to evaluate the variable and will generate an error message stating so. For example, if the variable requires a quantity from a "compute"_compute.html that has not been invoked on the current timestep, LAMMPS will generate an error. This means, for example, that such a variable cannot be evaluated before the first run has occurred. Likewise, in between runs, a variable containing a compute cannot be evaluated unless the compute was invoked on the last timestep of the preceding run, e.g. by thermodynamic output. One way to get around this problem is to perform a 0-timestep run before using the variable. For example, these commands variable t equal temp print "Initial temperature = $t" run 1000 :pre will generate an error if the run is the first run specified in the input script, because generating a value for the "t" variable requires a compute for calculating the temperature to be invoked. However, this sequence of commands would be fine: run 0 variable t equal temp print "Initial temperature = $t" run 1000 :pre The 0-timestep run initializes and invokes various computes, including the one for temperature, so that the value it stores is current and can be accessed by the variable "t" after the run has completed. Note that a 0-timestep run does not alter the state of the system, so it does not change the input state for the 1000-timestep run that follows. Also note that the 0-timestep run must actually use and invoke the compute in question (e.g. via "thermo"_thermo_style.html or "dump"_dump.html output) in order for it to enable the compute to be used in a variable after the run. Thus if you are trying to print a variable that uses a compute you have defined, you can insure it is invoked on the last timestep of the preceding run by including it in thermodynamic output. Unlike computes, "fixes"_fix.html will never generate an error if their values are accessed by a variable in between runs. They always return some value to the variable. However, the value may not be what you expect if the fix has not yet calculated the quantity of interest or it is not current. For example, the "fix indent"_fix_indent.html command stores the force on the indenter. But this is not computed until a run is performed. Thus if a variable attempts to print this value before the first run, zeroes will be output. Again, performing a 0-timestep run before printing the variable has the desired effect. (3) The variable may be evaluated incorrectly and LAMMPS may have no way to detect this has occurred. Consider the following sequence of commands: pair_coeff 1 1 1.0 1.0 run 1000 pair_coeff 1 1 1.5 1.0 variable e equal pe print "Final potential energy = $e" :pre The first run is performed using one setting for the pairwise potential defined by the "pair_style"_pair_style.html and "pair_coeff"_pair_coeff.html commands. The potential energy is evaluated on the final timestep and stored by the "compute pe"_compute_pe.html compute (this is done by the "thermo_style"_thermo_style.html command). Then a pair coefficient is changed, altering the potential energy of the system. When the potential energy is printed via the "e" variable, LAMMPS will use the potential energy value stored by the "compute pe"_compute_pe.html compute, thinking it is current. There are many other commands which could alter the state of the system between runs, causing a variable to evaluate incorrectly. The solution to this issue is the same as for case (2) above, namely perform a 0-timestep run before the variable is evaluated to insure the system is up-to-date. For example, this sequence of commands would print a potential energy that reflected the changed pairwise coefficient: pair_coeff 1 1 1.0 1.0 run 1000 pair_coeff 1 1 1.5 1.0 run 0 variable e equal pe print "Final potential energy = $e" :pre :line [Restrictions:] Indexing any formula element by global atom ID, such as an atom value, requires the "atom style"_atom_style.html to use a global mapping in order to look up the vector indices. By default, only atom styles with molecular information create global maps. The "atom_modify map"_atom_modify.html command can override the default, e.g. for atomic-style atom styles. All {universe}- and {uloop}-style variables defined in an input script must have the same number of values. [Related commands:] "next"_next.html, "jump"_jump.html, "include"_include.html, "temper"_temper.html, "fix print"_fix_print.html, "print"_print.html [Default:] none diff --git a/doc/utils/converters/lammpsdoc/txt2rst.py b/doc/utils/converters/lammpsdoc/txt2rst.py index 6949cb690..9fac2f063 100755 --- a/doc/utils/converters/lammpsdoc/txt2rst.py +++ b/doc/utils/converters/lammpsdoc/txt2rst.py @@ -1,410 +1,410 @@ #! /usr/bin/env python3 # LAMMPS Documentation Utilities # # Converter of LAMMPS documentation format to Sphinx ReStructured Text # # Copyright (C) 2015 Richard Berger # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import os import re import argparse from lammpsdoc import lammps_filters from lammpsdoc.txt2html import Markup, Formatting, TxtParser, TxtConverter class RSTMarkup(Markup): def __init__(self): super().__init__() def bold_start(self): return "**" def bold_end(self): return "**" def italic_start(self): return "*" def italic_end(self): return "*" def bold(self, text): """ RST requires a space after inline formats. For words which only partially apply a format add a backslash and whitespace to create valid RST""" text = re.sub(r'([^\s\\])\[([^\]\\]+)\]', r'\1\\ [\2]', text) text = re.sub(r'([^\\]?)\[([^\]\\]+)\]([^\s])', r'\1[\2]\\ \3', text) text = super().bold(text) return text def italic(self, text): """ RST requires a space after inline formats. For words which only partially apply a format add a backslash and whitespace to create valid RST""" text = re.sub(r'([^\s\\])\{([^\}\\]+)\}', r'\1\\ {\2}', text) text = re.sub(r'([^\\]?)\{([^\}\\]+)\}([^\s])', r'\1{\2}\\ \3', text) text = super().italic(text) return text def convert(self, text): text = self.escape_rst_chars(text) text = super().convert(text) text = self.inline_math(text) return text def escape_rst_chars(self, text): text = text.replace('*', '\\*') text = text.replace('^', '\\^') text = text.replace('|', '\\|') text = re.sub(r'([^"])_', r'\1\\_', text) return text def unescape_rst_chars(self, text): text = text.replace('\\*', '*') text = text.replace('\\^', '^') text = self.unescape_underscore(text) text = text.replace('\\|', '|') return text def unescape_underscore(self, text): return text.replace('\\_', '_') def inline_math(self, text): start_pos = text.find("\\(") end_pos = text.find("\\)") while start_pos >= 0 and end_pos >= 0: original = text[start_pos:end_pos+2] formula = original[2:-2] formula = self.unescape_rst_chars(formula) replacement = ":math:`" + formula.replace('\n', ' ').strip() + "`" text = text.replace(original, replacement) start_pos = text.find("\\(") end_pos = text.find("\\)") return text def create_link(self, content, href): content = content.strip() content = content.replace('\n', ' ') href = self.unescape_rst_chars(href) anchor_pos = href.find('#') - if anchor_pos >= 0: + if anchor_pos >= 0 and not href.startswith('http'): href = href[anchor_pos+1:] return ":ref:`%s <%s>`" % (content, href) if href in self.references: return ":ref:`%s <%s>`" % (content, href) elif href in self.aliases: href = "%s_" % href elif href.endswith('.html') and not href.startswith('http') and 'USER/atc' not in href: href = href[0:-5] return ":doc:`%s <%s>`" % (content, href) return "`%s <%s>`_" % (content, href) class RSTFormatting(Formatting): RST_HEADER_TYPES = '#*=-^"' def __init__(self, markup): super().__init__(markup) self.indent_level = 0 def paragraph(self, content): if self.indent_level > 0: return '\n' + self.list_indent(content.strip(), self.indent_level) return content.strip() + "\n" def center(self, content): return content def linebreak(self, content): return content.strip() def preformat(self, content): content = self.markup.unescape_underscore(content) if self.indent_level > 0: return self.list_indent("\n.. parsed-literal::\n\n" + self.indent(content.rstrip()), self.indent_level) return "\n.. parsed-literal::\n\n" + self.indent(content.rstrip()) def horizontal_rule(self, content): return "\n----------\n\n" + content.strip() def image(self, content, file, link=None): if link and (link.lower().endswith('.jpg') or link.lower().endswith('.jpeg') or link.lower().endswith('.png') or link.lower().endswith('.gif')): converted = ".. thumbnail:: " + self.markup.unescape_rst_chars(link) + "\n" else: converted = ".. image:: " + self.markup.unescape_rst_chars(file) + "\n" if link: converted += " :target: " + self.markup.unescape_rst_chars(link) + "\n" if "c" in self.current_command_list: converted += " :align: center\n" return converted + content.strip() def named_link(self, paragraph, name): self.markup.add_internal_reference(name) return (".. _%s:\n\n" % name) + paragraph def define_link_alias(self, paragraph, alias, value): self.markup.add_link_alias(alias, value) return (".. _%s: %s\n\n" % (alias, value)) + paragraph def header(self, content, level): header_content = content.strip() header_content = re.sub(r'[0-9]+\.([0-9]*\.?)*\s+', '', header_content) header_underline = RSTFormatting.RST_HEADER_TYPES[level-1] * len(header_content) return header_content + "\n" + header_underline + "\n" def unordered_list_item(self, paragraph): return "* " + paragraph.strip().replace('\n', '\n ') def ordered_list_item(self, paragraph, index): if index is None: index = "#" return str(index) + ". " + paragraph.strip().replace('\n', '\n ') def definition_term(self, paragraph): return paragraph.strip() def definition_description(self, paragraph): return self.indent(paragraph.strip()) def unordered_list_begin(self, paragraph): self.indent_level += 1 return paragraph def unordered_list_end(self, paragraph): self.indent_level -= 1 return paragraph.rstrip() + '\n' def ordered_list_begin(self, paragraph): if paragraph.startswith('* '): paragraph = '#. ' + paragraph[2:] self.indent_level += 1 return paragraph def definition_list_begin(self, paragraph): return paragraph def definition_list_end(self, paragraph): return paragraph def ordered_list_end(self, paragraph): self.indent_level -= 1 return paragraph.rstrip() + '\n' def ordered_list(self, paragraph): paragraph = super().ordered_list(paragraph) return paragraph.rstrip() + '\n' def unordered_list(self, paragraph): paragraph = super().unordered_list(paragraph) return paragraph.rstrip() + '\n' def all_breaks(self, paragraph): indented = "" for line in paragraph.splitlines(): indented += "| %s\n" % line indented += "| \n" return indented def begin_document(self): return "" def end_document(self): return "" def raw_html(self, content): raw_directive = ".. raw:: html\n\n" return raw_directive + self.indent(content) def indent(self, content): indented = "" for line in content.splitlines(): indented += " %s\n" % line return indented def list_indent(self, content, level=1): indented = "" for line in content.splitlines(): indented += " " * level + ("%s\n" % line) return indented def get_max_column_widths(self, rows): num_columns = max([len(row) for row in rows]) max_widths = [0] * num_columns for columns in rows: for col_idx, column in enumerate(columns): max_widths[col_idx] = max(max_widths[col_idx], len(column.strip())+2) return max_widths def create_table_horizontal_line(self, max_widths): cell_borders = ['-' * width for width in max_widths] return '+' + '+'.join(cell_borders) + "+" def table(self, paragraph, configuration): paragraph = self.protect_rst_directives(paragraph) if configuration['num_columns'] == 0: rows = self.create_table_with_columns_based_on_newlines(paragraph, configuration['separator']) else: rows = self.create_table_with_fixed_number_of_columns(paragraph, configuration['separator'], configuration['num_columns']) column_widths = self.get_max_column_widths(rows) max_columns = len(column_widths) horizontal_line = self.create_table_horizontal_line(column_widths) + "\n" tbl = horizontal_line for row_idx in range(len(rows)): columns = rows[row_idx] tbl += "| " for col_idx in range(max_columns): if col_idx < len(columns): col = columns[col_idx].strip() else: col = "" tbl += col.ljust(column_widths[col_idx]-2, ' ') tbl += " |" if col_idx < max_columns - 1: tbl += " " tbl += "\n" tbl += horizontal_line tbl = self.restore_rst_directives(tbl) return tbl def protect_rst_directives(self, content): content = content.replace(":doc:", "0DOC0") content = content.replace(":ref:", "0REF0") return content def restore_rst_directives(self, content): content = content.replace("0DOC0", ":doc:") content = content.replace("0REF0", ":ref:") return content def math(self, content): eqs = content.split(r'\end{equation}') text = "" if len(eqs) > 1: post = eqs[-1].strip() eqs = eqs[0:-1] else: post = "" for eq in eqs: if len(eq.strip()) == 0: continue parts = eq.split(r'\begin{equation}') assert(len(parts) == 1 or len(parts) == 2) if len(parts) == 2: start = parts[0].strip() body = parts[1] else: start = "" body = parts[0] body = self.markup.unescape_rst_chars(body) if len(start) > 0: text += start + "\n" text += "\n.. math::\n\n" text += self.indent(r'\begin{equation}' + body.strip('\n') + r'\end{equation}') text += "\n" return text + post class Txt2Rst(TxtParser): def __init__(self): super().__init__() self.markup = RSTMarkup() self.format = RSTFormatting(self.markup) self.register_filters() def register_filters(self): self.paragraph_filters.append(lammps_filters.detect_and_format_notes) self.document_filters.append(lammps_filters.filter_file_header_until_first_horizontal_line) self.document_filters.append(lammps_filters.detect_and_add_command_to_index) self.document_filters.append(lammps_filters.filter_multiple_horizontal_rules) self.document_filters.append(lammps_filters.promote_doc_keywords) self.document_filters.append(lammps_filters.merge_preformatted_sections) def is_ignored_textblock_begin(self, line): return line.startswith('') def is_ignored_textblock_end(self, line): return line.startswith('') def is_raw_textblock_begin(self, line): return line.startswith('') def order_commands(self, commands): if 'ule' in commands and 'l' in commands and commands.index('ule') > commands.index('l'): return commands elif 'ole' in commands and 'l' in commands and commands.index('ole') > commands.index('l'): return commands return super().order_commands(commands) def transform_paragraphs(self, content): if self.format.indent_level > 0: raise Exception("unbalanced number of ulb,ule or olb,ole pairs!") return super().transform_paragraphs(content) class Txt2RstConverter(TxtConverter): def get_argument_parser(self): parser = argparse.ArgumentParser(description='converts a text file with simple formatting & markup into ' 'Restructured Text for Sphinx.') parser.add_argument('-x', metavar='file-to-skip', dest='skip_files', action='append') parser.add_argument('files', metavar='file', nargs='+', help='one or more files to convert') return parser def create_converter(self, args): return Txt2Rst() def get_output_filename(self, path): filename, ext = os.path.splitext(path) return filename + ".rst" def main(): app = Txt2RstConverter() app.run() if __name__ == "__main__": main() diff --git a/doc/utils/converters/tests/test_txt2rst.py b/doc/utils/converters/tests/test_txt2rst.py index f74f8b70d..9bdb5b2e4 100644 --- a/doc/utils/converters/tests/test_txt2rst.py +++ b/doc/utils/converters/tests/test_txt2rst.py @@ -1,522 +1,527 @@ # LAMMPS Documentation Utilities # # Copyright (C) 2015 Richard Berger # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import io import tempfile import unittest from lammpsdoc import txt2rst class TestBasicFormatting(unittest.TestCase): def setUp(self): self.txt2rst = txt2rst.Txt2Rst() def test_empty_string(self): self.assertEqual(self.txt2rst.convert(""), "") def test_single_paragraph(self): self.assertEqual("Hello World!\n\n", self.txt2rst.convert("Hello World!\n")) def test_two_paragraphs(self): s = self.txt2rst.convert("Hello World!\n\nBye World!\n") self.assertEqual("Hello World!\n\n" "Bye World!\n\n", s) def test_line_concat(self): s = self.txt2rst.convert("Hello World!\\\nBye World!\n") self.assertEqual(s, "Hello World!Bye World!\n\n") def test_html_pass_through(self): s = self.txt2rst.convert("
Raw HTML
\n") self.assertEqual(s, ".. raw:: html\n\n" "
Raw HTML
\n\n") def test_ignore_html_only_block(self): s = self.txt2rst.convert("\n" "content :p\n" "\n") self.assertEqual("", s) def test_pass_through_raw_rst(self): raw_rst = ".. toctree::\n" \ " :maxdepth: 2\n" \ " :numbered:\n" \ "\n" \ " Introduction\n" s = self.txt2rst.convert("\n") self.assertEqual(raw_rst, s) class TestMarkup(unittest.TestCase): def setUp(self): self.markup = txt2rst.RSTMarkup() self.txt2rst = txt2rst.Txt2Rst() def test_bold(self): self.assertEqual("**bold**", self.markup.convert("[bold]")) def test_italic(self): self.assertEqual("*italic*", self.markup.convert("{italic}")) def test_escape_markup(self): s = self.markup.convert("[bold] = \\[bold\\]\n" "{italic} = \\{italic\\}\n") self.assertEqual("**bold** = [bold]\n" "*italic* = {italic}\n", s) def test_escape_rst_characters(self): s = self.markup.convert("[*bold] and {italic*}") self.assertEqual("**\*bold** and *italic\**", s) def test_escape_rst_characters(self): s = self.markup.convert("[|bold|] and {|italic|}") self.assertEqual("**\|bold\|** and *\|italic\|*", s) def test_escape_hat_character(self): s = self.markup.convert("x^2") self.assertEqual("x\^2", s) def test_escape_underscore(self): s = self.markup.convert("x_") self.assertEqual("x\_", s) def test_paragraph_with_italic(self): self.assertEqual("A sentence with a *italic* word", self.markup.convert("A sentence with a {italic} word")) def test_paragraph_with_partial_italic(self): self.assertEqual("A sentence with a partial *italic*\ normal word", self.markup.convert("A sentence with a partial {italic}normal word")) def test_paragraph_with_partial_bold(self): self.assertEqual("A sentence with a partial **bold**\ normal word", self.markup.convert("A sentence with a partial [bold]normal word")) def test_paragraph_with_mixed_formats(self): self.assertEqual("A sentence with a partial normal\ **bold**\ *italic*\ normal word", self.markup.convert("A sentence with a partial normal[bold]{italic}normal word")) def test_link_markup(self): self.assertEqual("`Text `_", self.markup.convert('"Text"_link')) def test_document_cross_reference_link(self): self.assertEqual(":doc:`Text `", self.markup.convert('"Text"_link.html')) def test_user_atc_link(self): self.assertEqual("`Text `_", self.markup.convert('"Text"_USER/atc/link.html')) def test_external_link(self): self.assertEqual("`Text `_", self.markup.convert('"Text"_http://site/index.html')) def test_multiline_link_markup(self): s = self.txt2rst.convert('"Te\n' 'xt"_link\n') self.assertEqual("`Te xt `_\n\n", s) def test_ignore_punctuation_in_link(self): self.assertEqual("`Text `_.", self.markup.convert('"Text"_link.')) self.assertEqual("`Text `_,", self.markup.convert('"Text"_link,')) self.assertEqual("`Text `_;", self.markup.convert('"Text"_link;')) self.assertEqual("`Text `_:", self.markup.convert('"Text"_link:')) self.assertEqual("`Text `_?", self.markup.convert('"Text"_link?')) self.assertEqual("`Text `_!", self.markup.convert('"Text"_link!')) self.assertEqual("`Text `_(", self.markup.convert('"Text"_link(')) self.assertEqual("`Text `_)", self.markup.convert('"Text"_link)')) class TestFormatting(unittest.TestCase): def setUp(self): self.txt2rst = txt2rst.Txt2Rst() def test_paragraph_formatting(self): s = self.txt2rst.convert("Hello :p\n") self.assertEqual("Hello\n\n", s) def test_two_paragraphs_through_formatting(self): text = "Hello :p\nBye :p\n" p = list(self.txt2rst.paragraphs(text)) s = self.txt2rst.convert(text) self.assertEqual(len(p), 2) self.assertEqual(s, "Hello\n" "\n" "Bye\n" "\n") def test_break_formatting(self): s = self.txt2rst.convert("Hello :b\n") self.assertEqual("Hello\n", s) def test_preformat_formatting(self): s = self.txt2rst.convert("Hello :pre\n") self.assertEqual("\n.. parsed-literal::\n\n" " Hello\n\n", s) def test_preformat_formatting_with_indentation(self): s = self.txt2rst.convert(" Hello\n" " World :pre\n") self.assertEqual("\n.. parsed-literal::\n\n" " Hello\n" " World\n\n", s) def test_preformat_formatting_with_underscore(self): s = self.txt2rst.convert("if MPI.COMM_WORLD.rank == 0:\n" " print(\"Potential energy: \", L.eval(\"pe\")) :pre\n") self.assertEqual("\n.. parsed-literal::\n\n" " if MPI.COMM_WORLD.rank == 0:\n" " print(\"Potential energy: \", L.eval(\"pe\"))\n\n", s) def test_header_formatting(self): s = self.txt2rst.convert("Level 1 :h1\n" "Level 2 :h2\n" "Level 3 :h3\n" "Level 4 :h4\n" "Level 5 :h5\n" "Level 6 :h6\n") self.assertEqual("Level 1\n" "#######\n" "\n" "Level 2\n" "*******\n" "\n" "Level 3\n" "=======\n" "\n" "Level 4\n" "-------\n" "\n" "Level 5\n" "^^^^^^^\n" "\n" "Level 6\n" '"""""""\n' '\n', s) def test_filter_header_numbers(self): s = self.txt2rst.convert("1.1 Level :h1\n") self.assertEqual("Level\n" "#####\n\n", s) def test_filter_header_numbers_deep(self): s = self.txt2rst.convert("1.1.1.1.1 Level :h1\n") self.assertEqual("Level\n" "#####\n\n", s) def test_no_filter_date(self): s = self.txt2rst.convert("9 Sept 2016 version :h1\n") self.assertEqual("9 Sept 2016 version\n" "###################\n\n", s) def test_all_breaks(self): s = self.txt2rst.convert("one\n" "two\n" "three :all(b)\n") self.assertEqual("| one\n" "| two\n" "| three \n" "| \n" "\n", s) def test_links_with_all_breaks(self): s = self.txt2rst.convert("\"one\"_link\n" "\"two\"_link\n" "\"three\"_link :all(b)\n") self.assertEqual("| `one `_\n" "| `two `_\n" "| `three `_ \n" "| \n" "\n", s) class TestListFormatting(unittest.TestCase): def setUp(self): self.txt2rst = txt2rst.Txt2Rst() def test_unordered_list(self): s = self.txt2rst.convert("one\n" "two\n" "three :ul\n") self.assertEqual("* one\n" "* two\n" "* three\n\n", s) def test_elementwise_unordered_list(self): s = self.txt2rst.convert("one :ulb,l\n" "two :l\n" "three :ule,l\n") self.assertEqual("* one\n" "* two\n" "* three\n\n", s) def test_elementwise_unordered_list_reverse(self): s = self.txt2rst.convert("one :ulb,l\n" "two :l\n" "three :l,ule\n") self.assertEqual("* one\n" "* two\n" "* three\n\n", s) def test_multi_line_unordered_list_elements(self): s = self.txt2rst.convert("one :ulb,l\n" "two\n" "words :l\n" "three :ule,l\n") self.assertEqual("* one\n" "* two\n" " words\n" "* three\n\n", s) def test_ordered_list(self): s = self.txt2rst.convert("one\n" "two\n" "three :ol\n") self.assertEqual("1. one\n" "2. two\n" "3. three\n\n", s) def test_elementwise_ordered_list(self): s = self.txt2rst.convert("one :olb,l\n" "two :l\n" "three :ole,l\n") self.assertEqual("#. one\n" "#. two\n" "#. three\n\n", s) def test_multi_line_ordered_list_elements(self): s = self.txt2rst.convert("one :olb,l\n" "two\n" "words :l\n" "three :ole,l\n") self.assertEqual("#. one\n" "#. two\n" " words\n" "#. three\n\n", s) def test_paragraphs_ordered_list(self): s = self.txt2rst.convert("first\n" "paragraph :olb,l\n" "second\n" "paragraph :l\n" "third\n" "paragraph :ole,l\n") self.assertEqual("#. first\n" " paragraph\n" "#. second\n" " paragraph\n" "#. third\n" " paragraph\n\n", s) def test_paragraphs_unordered_list(self): s = self.txt2rst.convert("first\n" "paragraph :ulb,l\n" "second\n" "paragraph :l\n" "third\n" "paragraph :ule,l\n") self.assertEqual("* first\n" " paragraph\n" "* second\n" " paragraph\n" "* third\n" " paragraph\n\n", s) def test_definition_list(self): s = self.txt2rst.convert("A\n" "first\n" "B\n" "second :dl\n") self.assertEqual("A\n" " first\n" "\n" "B\n" " second\n" "\n\n", s) def test_multi_paragraph_lists(self): s = self.txt2rst.convert("first\n" "paragraph of first bullet :ulb,l\n\n" "second paragraph of first bullet\n\n" "first paragraph of second bullet :l\n\n" ":ule\n") self.assertEqual("* first\n" " paragraph of first bullet\n" "\n" " second paragraph of first bullet\n" "\n" "* first paragraph of second bullet\n\n\n", s) def test_multi_paragraph_lists_with_listing(self): s = self.txt2rst.convert("first\n" "paragraph of first bullet :ulb,l\n\n" "code1 :pre\n" "or\n" "\n" "first paragraph of second bullet :l\n\n" ":ule\n") self.assertEqual("* first\n" " paragraph of first bullet\n" " \n" " .. parsed-literal::\n" " \n" " code1\n" "\n\n" " or\n" "\n" "* first paragraph of second bullet\n\n\n", s) class TestSpecialCommands(unittest.TestCase): def setUp(self): self.txt2rst = txt2rst.Txt2Rst() def test_line(self): self.txt2rst.document_filters = [] s = self.txt2rst.convert("one :line\n") self.assertEqual("\n" "----------\n" "\n" "one\n", s) def test_image(self): s = self.txt2rst.convert("one :image(file)\n") self.assertEqual(".. image:: file\n" "one\n", s) def test_centered_image(self): s = self.txt2rst.convert(":image(file),c\n") self.assertEqual(".. image:: file\n" " :align: center\n\n", s) def test_image_with_link(self): s = self.txt2rst.convert("one :image(file,link)\n") self.assertEqual(s, ".. image:: file\n" " :target: link\n" "one\n") def test_thumbnail_image(self): # requires sphinxcontrib-images extension s = self.txt2rst.convert("one :image(file,large_file.jpg)\n") self.assertEqual(s, ".. thumbnail:: large_file.jpg\n" "one\n") def test_internal_reference_link(self): s = self.txt2rst.convert("one :link(name)\n" "a \"link\"_name to above\n") self.assertEqual(".. _name:\n" "\n" "one \n\n" "a :ref:`link ` to above\n\n", s) def test_local_anchor_link(self): s = self.txt2rst.convert("one :link(name)\n" "a \"link\"_#name to above\n") self.assertEqual(".. _name:\n" "\n" "one \n\n" "a :ref:`link ` to above\n\n", s) + def test_external_anchor_link(self): + s = self.txt2rst.convert('some text "containing a\n' + 'link"_http://lammps.sandia.gov/movies.html#granregion with an anchor') + self.assertEqual('some text `containing a link `_ with an anchor\n\n', s) + def test_define_link_alias(self): s = self.txt2rst.convert("one :link(alias,value)\n" "\"test\"_alias\n") self.assertEqual(".. _alias: value\n\n" "one \n" "\n" "`test `_\n\n", s) class TestTableCommand(unittest.TestCase): def setUp(self): self.txt2rst = txt2rst.Txt2Rst() def test_convert_table_to_grid_table(self): s = self.txt2rst.convert("a,b,c :tb") table = "+---+---+---+\n" \ "| a | b | c |\n" \ "+---+---+---+\n\n" self.assertEqual(table, s) def test_avoid_rst_syntax_conflicts_with_table_separator(self): s = self.txt2rst.convert("\"a\"_test.html: b: c :tb(s=:)") table = "+-----------------+---+---+\n" \ "| :doc:`a ` | b | c |\n" \ "+-----------------+---+---+\n\n" self.assertEqual(table, s) class TestTxt2RstCLI(unittest.TestCase): def setUp(self): self.out = io.StringIO() self.err = io.StringIO() self.app = txt2rst.Txt2RstConverter() def test_convert_single_file(self): with tempfile.NamedTemporaryFile(mode='w+t') as f: f.write('Hello World!\n') f.flush() args = [f.name] self.app.run(args=args, out=self.out, err=self.err) self.assertEqual("Hello World!\n\n", self.out.getvalue()) self.assertEqual("Converting " + f.name + " ...\n", self.err.getvalue()) class TestMathMarkup(unittest.TestCase): def setUp(self): self.markup = txt2rst.RSTMarkup() self.txt2rst = txt2rst.Txt2Rst() def test_detect_latex_equation(self): s = self.txt2rst.convert("\\begin\\{equation\\} T_\\{ij\\}(r_\\{ij\\}) = 1 - \\left( 1 +\n" "\\frac\{s_\\{ij\} r_\\{ij\} \\}\\{2\\} \\right)\n" "\\exp \\left( - s_\\{ij\\} r_\\{ij\\} \\right) \\end\\{equation\\}\n") self.assertEqual("\n.. math::\n\n" " \\begin{equation} T_{ij}(r_{ij}) = 1 - \\left( 1 +\n" " \\frac{s_{ij} r_{ij} }{2} \\right)\n" " \\exp \\left( - s_{ij} r_{ij} \\right) \\end{equation}\n\n", s) def test_detect_latex_equation_with_mult(self): s = self.txt2rst.convert("\\begin\\{equation\\} a = b * c \\end\\{equation\\}\n") self.assertEqual("\n.. math::\n\n" " \\begin{equation} a = b * c \\end{equation}\n\n", s) def test_detect_latex_equation_with_pow(self): s = self.txt2rst.convert("\\begin\\{equation\\} a = b^c \\end\\{equation\\}\n") self.assertEqual("\n.. math::\n\n" " \\begin{equation} a = b^c \\end{equation}\n\n", s) def test_detect_inline_latex_equation(self): s = self.txt2rst.convert("Masses: \\begin\\{equation\\} M' = M + m \\end\\{equation\\}\n" "\\begin\\{equation\\} m' = \\frac \\{M\\, m \\} \\{M'\\} \\end\\{equation\\}\n") self.assertEqual("Masses:\n" "\n.. math::\n\n" " \\begin{equation} M' = M + m \end{equation}\n" "\n" "\n.. math::\n" "\n" " \\begin{equation} m' = \\frac {M\\, m } {M'} \\end{equation}\n" "\n", s) def test_detect_inline_math(self): self.assertEqual(":math:`x^2`", self.markup.convert("\\( x^2 \\)")) def test_detect_inline_math_mult(self): self.assertEqual(":math:`x * 2`", self.markup.convert("\\( x * 2 \\)")) def test_detect_multiline_inline_math(self): line = "\\(\\sqrt \\{ \\frac \\{2\, k_B \\mathtt\\{Tcom\\}\, m'\\}\n" \ "\\{\\mathrm dt\\, \\mathtt\\{damp\\_com\\} \\}\n" \ "\\} \\). :b\n" \ "\(f_r'\) is a random force proportional to\n" expected = ":math:`\\sqrt { \\frac {2\\, k_B \\mathtt{Tcom}\, m'} " \ "{\\mathrm dt\\, \\mathtt{damp\\_com} } " \ "}`.\n" \ ":math:`f_r'` is a random force proportional to\n\n" self.assertEqual(expected, self.txt2rst.convert(line)) if __name__ == '__main__': unittest.main() diff --git a/examples/README b/examples/README index 462fa93e1..a6925878e 100644 --- a/examples/README +++ b/examples/README @@ -1,176 +1,177 @@ LAMMPS example problems There are 3 flavors of sub-directories in this file, each with sample problems you can run with LAMMPS. lower-case directories = simple test problems for LAMMPS and its packages upper-case directories = more complex problems USER directory with its own sub-directories = tests for USER packages Each is discussed below. ------------------------------------------ Lower-case directories Each of these sub-directories contains a sample problem you can run with LAMMPS. Most are 2d models so that they run quickly, requiring a few seconds to a few minutes to run on a desktop machine. Each problem has an input script (in.*) and produces a log file (log.*) and (optionally) a dump file (dump.*) or image files (image.*) or movie (movie.mpg) when it runs. Some use a data file (data.*) of initial coordinates as additional input. Some require that you install one or more optional LAMMPS packages. A few sample log file outputs on different machines and different numbers of processors are included in the directories to compare your answers to. E.g. a log file like log.crack.date.foo.P means it ran on P processors of machine "foo" with the dated version of LAMMPS. Note that these problems should get statistically similar answers when run on different machines or different numbers of processors, but not identical answers to those in the log of dump files included here. See the Errors section of the LAMMPS documentation for more discussion. Most of the example input scripts have commented-out lines that produce dump snapshots of the running simulation in any of 3 formats. If you uncomment the dump command in the input script, a text dump file will be produced, which can be animated by various visualization programs (see http://lammps.sandia.gov/viz.html) such as VMD or AtomEye. It can also be animated using the xmovie tool described in the Additional Tools section of the LAMMPS documentation. If you uncomment the dump image command in the input script, and assuming you have built LAMMPS with a JPG library, JPG snapshot images will be produced when the simulation runs. They can be quickly post-processed into a movie using commands described on the dump image doc page. If you uncomment the dump movie command in the input script, and assuming you have built LAMMPS with the FFMPEG library, an MPG movie will be produced when the simulation runs. The movie file can be played using various viewers, such as mplayer or QuickTime. Animations of many of these examples can be viewed on the Movies section of the LAMMPS WWW Site. These are the sample problems and their output in the various sub-directories: accelerate: use of all the various accelerator packages balance: dynamic load balancing, 2d system body: body particles, 2d system cmap: CMAP 5-body contributions to CHARMM force field colloid: big colloid particles in a small particle solvent, 2d system coreshell: adiabatic core/shell model comb: models using the COMB potential controller: use of fix controller as a thermostat crack: crack propagation in a 2d solid deposit: deposition of atoms and molecules onto a 3d substrate dipole: point dipolar particles, 2d system dreiding: methanol via Dreiding FF eim: NaCl using the EIM potential ellipse: ellipsoidal particles in spherical solvent, 2d system flow: Couette and Poiseuille flow in a 2d channel friction: frictional contact of spherical asperities between 2d surfaces +granregion: use of fix wall/region/gran as boundary on granular particles hugoniostat: Hugoniostat shock dynamics indent: spherical indenter into a 2d solid kim: use of potentials in Knowledge Base for Interatomic Models (KIM) meam: MEAM test for SiC and shear (same as shear examples) melt: rapid melt of 3d LJ system micelle: self-assembly of small lipid-like molecules into 2d bilayers min: energy minimization of 2d LJ melt msst: MSST shock dynamics nb3b: use of nonbonded 3-body harmonic pair style neb: nudged elastic band (NEB) calculation for barrier finding nemd: non-equilibrium MD of 2d sheared system obstacle: flow around two voids in a 2d channel 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 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 snap: use of SNAP potential for Ta srd: stochastic rotation dynamics (SRD) particles as solvent snap: NVE dynamics for BCC tantalum crystal using SNAP potential streitz: Streitz-Mintmire potential for Al2O3 tad: temperature-accelerated dynamics of vacancy diffusion in bulk Si vashishta: models using the Vashishta potential voronoi: test of Voronoi tesselation in compute voronoi/atom Here is a src/Make.py command which will perform a parallel build of a LAMMPS executable "lmp_mpi" with all the packages needed by all the examples, with the exception of the accelerate sub-directory. See the accelerate/README for Make.py commands suitable for its example scripts. cd src 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: cd indent cp ../../src/lmp_mpi . # copy LAMMPS executable to this dir lmp_mpi < in.indent # run the problem Running the simulation produces the files {dump.indent} and {log.lammps}. You can visualize the dump file as follows: ../../tools/xmovie/xmovie -scale dump.indent If you uncomment the dump image line(s) in the input script a series of JPG images will be produced by the run. These can be viewed individually or turned into a movie or animated by tools like ImageMagick or QuickTime or various Windows-based tools. See the dump image doc page for more details. E.g. this Imagemagick command would create a GIF file suitable for viewing in a browser. % convert -loop 1 *.jpg foo.gif ------------------------------------------ Upper-case directories The ASPHERE directory has examples of how to model aspherical particles with or without solvent, in 3 styles LAMMPS provides. Namely point ellipsoids, rigid bodies, and generalized aspherical bodies built from line/triangle surface facets in 2d/3d. See the ASPHERE/README file to get started. The COUPLE directory has examples of how to use LAMMPS as a library, either by itself or in tandem with another code or library. See the COUPLE/README file to get started. The ELASTIC directory has an example script for computing elastic constants at zero temperature, using an Si example. See the ELASTIC/in.elastic file for more info. The ELASTIC_T directory has an example script for computing elastic constants at finite temperature, using an Si example. See the ELASTIC_T/in.elastic file for more info. The HEAT directory has example scripts for heat exchange algorithms (e.g. used for establishing a thermal gradient), using two different methods. See the HEAT/README file for more info. The KAPPA directory has example scripts for computing the thermal conductivity (kappa) of a LJ liquid using 5 different methods. See the KAPPA/README file for more info. The MC directory has an example script for using LAMMPS as an energy-evaluation engine in a iterative Monte Carlo energy-relaxation loop. The USER directory contains subdirectories of user-provided example scripts for ser packages. See the README files in those directories for more info. See the doc/Section_start.html file for more info about installing and building user packages. The VISCOSITY directory has example scripts for computing the viscosity of a LJ liquid using 4 different methods. See the VISCOSITY/README file for more info. diff --git a/examples/USER/quip/in.gap b/examples/USER/quip/in.gap index 8e3c3d701..37667e39b 100644 --- a/examples/USER/quip/in.gap +++ b/examples/USER/quip/in.gap @@ -1,23 +1,22 @@ # Test of GAP potential for Si system units metal boundary p p p atom_style atomic read_data data_gap pair_style quip pair_coeff * * gap_example.xml "Potential xml_label=GAP_2015_2_20_0_10_54_35_765" 14 neighbor 0.3 bin neigh_modify delay 10 fix 1 all nve thermo 10 timestep 0.001 dump 1 all custom 10 dump.gap id fx fy fz -dump_modify 1 format "%d %20.15g %20.15g %20.15g" run 40 diff --git a/examples/USER/quip/in.sw b/examples/USER/quip/in.sw index a3c1df704..c1367ac80 100644 --- a/examples/USER/quip/in.sw +++ b/examples/USER/quip/in.sw @@ -1,23 +1,22 @@ # Test of SW potential for Si system units metal boundary p p p atom_style atomic read_data data_sw pair_style quip pair_coeff * * sw_example.xml "IP SW" 14 neighbor 0.3 bin neigh_modify delay 10 fix 1 all nve thermo 10 timestep 0.001 dump 1 all custom 10 dump.sw id fx fy fz -dump_modify 1 format "%d %20.15g %20.15g %20.15g" run 1 diff --git a/examples/granregion/in.granregion.box b/examples/granregion/in.granregion.box new file mode 100644 index 000000000..91f06744d --- /dev/null +++ b/examples/granregion/in.granregion.box @@ -0,0 +1,66 @@ +# pouring spheres into container box + +units lj +atom_style sphere +boundary f f f +dimension 3 +comm_modify vel yes + +region box block -10 10 -10 10 -10 10 units box +create_box 2 box + +pair_style hybrid gran/hooke 4000.0 NULL 100.0 NULL 0.5 1 +pair_coeff * * gran/hooke + +region container block -6 6 -6 6 -6 6 units box +fix container all wall/gran/region hooke/history & + 4000.0 NULL 100.0 NULL 0.5 1 region container + +neighbor 0.3 bin +neigh_modify delay 0 every 1 check yes + +fix 2 all nve/sphere +fix 3 all gravity 1.0 vector 0 0 -1 + +region slab block -2 2 -2 2 -2 2 units box +fix ins all pour 100 2 4767548 vol 0.4 10 & + diam one 1.0 region slab ignore + +timestep 0.005 + +compute 1 all temp +compute_modify 1 dynamic yes + +compute 2 all temp/sphere +compute_modify 2 dynamic yes + +thermo 100 +thermo_style custom step atoms temp c_1 c_2 press +thermo_modify lost ignore +compute_modify thermo_temp dynamic yes + +#dump 2 all image 100 image.*.jpg type type & +# zoom 1.4 adiam 1.0 box no 0.0 axes yes 0.9 0.03 +#dump_modify 2 pad 5 + +run 5000 + +region container delete +variable theta equal (step-5000)*(4.0*PI/5000) +region container block -6 6 -6 6 -6 6 units box & + rotate v_theta 0 0 0 0 0 1 +run 5000 + +region container delete +region container block -6 6 -6 6 -6 6 units box +run 5000 + +region container delete +variable theta equal (step-15000)*(4.0*PI/5000) +region container block -6 6 -6 6 -6 6 units box & + rotate v_theta 0 0 0 1 1 1 +run 5000 + +region container delete +region container block -6 6 -6 6 -6 6 units box +run 5000 diff --git a/examples/granregion/in.granregion.funnel b/examples/granregion/in.granregion.funnel new file mode 100644 index 000000000..63e79a711 --- /dev/null +++ b/examples/granregion/in.granregion.funnel @@ -0,0 +1,157 @@ +# pour particles into cone-shaped funnel, settle them, let them run out bottom + +variable name string funnel_pour + +thermo_modify flush yes +units si +variable PI equal 3.141592653589 +variable seed equal 14314 + +############################################### +# Geometry-related parameters +############################################### + +variable xlo equal 10 +variable xhi equal 40 +variable ylo equal 10 +variable yhi equal 40 +variable zlo equal -20 +variable zhi equal 50 + +variable xc equal 25 +variable yc equal 25 + +variable zconehi equal 50 +variable zconelo equal 10 +variable zcyllo equal 0 +variable radconelo equal 2 +variable radconehi equal 20 + +################################################ +# Particle sizes +################################################ + +variable rlo equal 0.25 +variable rhi equal 0.5 +variable dlo equal 2.0*${rlo} +variable dhi equal 2.0*${rhi} + +variable skin equal ${rhi} + +############################################### +# Granular contact parameters +############################################### + +variable coeffRes equal 0.1 +variable coeffFric equal 0.5 + +variable density equal 1.0 +variable EYoung equal 10^5 +variable Poisson equal 2.0/7.0 +variable GShear equal ${EYoung}/(2*(1+${Poisson})) + +variable gravity equal 1.0 + +variable reff equal 0.5*(${rhi}+${rlo}) +variable meff equal ${density}*4.0/3.0*${PI}*${reff}^3 +variable min_mass equal ${density}*4.0/3.0*${PI}*${rlo}*${rlo}*${rlo} +variable max_mass equal ${density}*4.0/3.0*${PI}*${rhi}*${rhi}*${rhi} + +## Typical way to set kn, kt, etc.: +variable kn equal 4.0*${GShear}/(3*(1-${Poisson})) +variable kt equal 4.0*${GShear}/(2-${Poisson}) + +variable a equal (-2.0*log(${coeffRes})/${PI})^2 +variable gamma_n equal sqrt($a*2*${kn}/${min_mass}/(1+0.25*$a)) +variable gamma_t equal ${gamma_n}*0.5 + +variable tcol equal ${PI}/sqrt(2*${kn}/${min_mass}-${gamma_n}/4.0) + +variable dt equal ${tcol}*0.05 +timestep ${dt} + +############################################### +variable dumpfreq equal 1000 +variable logfreq equal 1000 + +newton off +atom_style sphere + +boundary p p f + +region boxreg block ${xlo} ${xhi} ${ylo} ${yhi} ${zlo} ${zhi} +create_box 1 boxreg + +pair_style gran/hertz/history & + ${kn} ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 +pair_coeff * * + +neighbor ${skin} bin +thermo ${logfreq} + +comm_style brick +comm_modify mode multi group all vel yes +balance 1.1 shift xyz 20 1.1 +fix bal all balance 10000 1.1 shift xyz 20 1.01 + +####################### Options specific to pouring ######################### + +# insertion region for fix/pour + +region insreg cylinder z ${xc} ${yc} 10 30 50 side in units box + +# define cone and cylinder regions - see lammps doc on region command +# note new open options + +region cylreg cylinder z ${xc} ${yc} ${radconelo} & + ${zcyllo} ${zconelo} side in units box & + open 2 #Top is open + +region conereg cone z ${xc} ${yc} ${radconelo} ${radconehi} & + ${zconelo} ${zconehi} side in units box & + open 1 open 2 #Bottom and top are open + +region hopreg union 2 conereg cylreg + +fix grav all gravity ${gravity} vector 0 0 -1 +fix 1 all nve/sphere + + +fix hopper3 all wall/gran/region hertz/history & + ${kn} ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 region hopreg + +fix ins all pour 2000 1 42424 region insreg & + diam range ${dlo} ${dhi} dens ${density} ${density} + +#dump 1 all custom ${dumpfreq} ${name}.dump & +# id type mass diameter x y z + +#dump 2 all image 4000 image.*.jpg type type & +# axes yes 0.8 0.02 view 60 -30 zoom 3.0 & +# box no 0.0 axes no 0.0 0.0 +#dump_modify 2 pad 6 + +thermo_style custom step cpu atoms ke +thermo_modify flush yes lost warn + +# Initial run to fill up the cone + +run 20000 +unfix ins +run 150000 + +# remove "plug" - need to redefine cylinder region & union + +region cylreg delete +region hopreg delete +region cylreg cylinder z ${xc} ${yc} ${radconelo} & + ${zcyllo} ${zconelo} side in units box & + open 1 open 2 #Bottom & top are open + +region hopreg union 2 cylreg conereg + +unfix hopper3 +fix hopper3 all wall/gran/region hertz/history & + ${kn} ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 region hopreg + +run 100000 diff --git a/examples/granregion/in.granregion.mixer b/examples/granregion/in.granregion.mixer new file mode 100644 index 000000000..f9a9d04cb --- /dev/null +++ b/examples/granregion/in.granregion.mixer @@ -0,0 +1,96 @@ +variable name string mixer + +thermo_modify flush yes +variable seed equal 14314 + +############################################### +# Particle parameters +################################################ + +variable rlo equal 0.3 +variable rhi equal 0.6 +variable dlo equal 2.0*${rlo} +variable dhi equal 2.0*${rhi} +variable skin equal ${rhi} + +variable coeffRes equal 0.1 +variable coeffFric equal 0.5 + +variable kn equal 10^5 +variable kt equal 0.2*${kn} + +variable gravity equal 1.0 +variable density equal 1.0 + +variable min_mass equal ${density}*4.0/3.0*PI*${rlo}*${rlo}*${rlo} +variable a equal (-2.0*log(${coeffRes})/PI)^2 +variable gamma_n equal sqrt($a*2*${kn}/${min_mass}/(1+0.25*$a)) +variable gamma_t equal ${gamma_n}*0.5 + +variable tcol equal PI/sqrt(2*${kn}/${min_mass}-${gamma_n}/4.0) + +variable dt equal ${tcol}*0.02 +timestep ${dt} + +############################################### + +variable dumpfreq equal 1000 +variable logfreq equal 1000 + +newton on +atom_style sphere + +boundary p p f + +region boxreg block 0 20 0 20 0 20 +create_box 1 boxreg + +pair_style gran/hertz/history & + ${kn} ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 +pair_coeff * * + +neighbor ${skin} bin +thermo ${logfreq} + +comm_style brick +comm_modify mode multi group all vel yes +balance 1.1 shift xyz 20 1.1 +fix bal all balance 10000 1.1 shift xyz 20 1.01 + +####################### Options specific to pouring ######################### + +region insreg cylinder z 10 10 8 10 18 side in units box +region cylreg cylinder z 10 10 10 0 20 side in units box + +variable theta equal (step/400000)*2*PI + +region b1 block 2 18 9 11 0 4 side out & + rotate v_theta 10 10 0 0 0 1 units box +region b2 block 9 11 2 18 0 3.99999 side out & + rotate v_theta 10 10 0 0 0 1 units box + +region mixer intersect 3 cylreg b1 b2 side in + +fix grav all gravity ${gravity} vector 0 0 -1 +fix 1 all nve/sphere + +fix mixwall all wall/gran/region hertz/history & + ${kn} ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 region mixer + +fix ins all pour 1000 1 42424 region insreg & + diam range ${dlo} ${dhi} dens ${density} ${density} + +#dump 1 all custom ${dumpfreq} ${name}_pour.dump & +# id type mass diameter x y z + +#dump 2 all image 4000 image.*.jpg type type & +# axes yes 0.8 0.02 view 60 -30 zoom 1.5 & +# box no 0.0 axes no 0.0 0.0 +#dump_modify 2 pad 6 + +thermo_style custom step cpu atoms ke v_theta +thermo_modify flush yes lost warn + +run 200000 +unfix ins +run 200000 diff --git a/examples/granregion/log.6Oct16.granregion.box.g++.1 b/examples/granregion/log.6Oct16.granregion.box.g++.1 new file mode 100644 index 000000000..ae2ec694e --- /dev/null +++ b/examples/granregion/log.6Oct16.granregion.box.g++.1 @@ -0,0 +1,468 @@ +LAMMPS (5 Oct 2016) +# pouring spheres into container box + +units lj +atom_style sphere +boundary f f f +dimension 3 +comm_modify vel yes + +region box block -10 10 -10 10 -10 10 units box +create_box 2 box +Created orthogonal box = (-10 -10 -10) to (10 10 10) + 1 by 1 by 1 MPI processor grid + +pair_style hybrid gran/hooke 4000.0 NULL 100.0 NULL 0.5 1 +pair_coeff * * gran/hooke + +region container block -6 6 -6 6 -6 6 units box +fix container all wall/gran/region hooke/history 4000.0 NULL 100.0 NULL 0.5 1 region container + +neighbor 0.3 bin +neigh_modify delay 0 every 1 check yes + +fix 2 all nve/sphere +fix 3 all gravity 1.0 vector 0 0 -1 + +region slab block -2 2 -2 2 -2 2 units box +fix ins all pour 100 2 4767548 vol 0.4 10 diam one 1.0 region slab ignore +Particle insertion: 48 every 566 steps, 100 by step 1133 + +timestep 0.005 + +compute 1 all temp +compute_modify 1 dynamic yes + +compute 2 all temp/sphere +compute_modify 2 dynamic yes + +thermo 100 +thermo_style custom step atoms temp c_1 c_2 press +thermo_modify lost ignore +compute_modify thermo_temp dynamic yes + +#dump 2 all image 100 image.*.jpg type type # zoom 1.4 adiam 1.0 box no 0.0 axes yes 0.9 0.03 +#dump_modify 2 pad 5 + +run 5000 +Neighbor list info ... + 1 neighbor list requests + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 1.3 + ghost atom cutoff = 1.3 + binsize = 0.65 -> bins = 31 31 31 +Memory usage per processor = 0.201172 Mbytes +Step Atoms Temp c_1 c_2 Press + 0 0 0 0 0 0 + 100 21 0.54270729 0.54270729 0.26473526 0.0013567682 + 200 21 0.87606961 0.87606961 0.42735103 0.002190174 + 300 21 1.1428374 1.1428374 0.55748167 0.0028570936 + 400 21 1.3543103 1.3543103 0.66829516 0.0033857758 + 500 21 1.0677786 1.0677786 0.53582407 0.0045048164 + 600 56 0.6744286 0.6744286 0.3502938 0.0047464584 + 700 56 0.75569283 0.75569283 0.39779462 0.0051953882 + 800 56 0.61597505 0.61597505 0.32943642 0.0086022783 + 900 56 0.65260802 0.65260802 0.34474044 0.0059298996 + 1000 56 0.51624952 0.51624952 0.28326898 0.0067827337 + 1100 56 0.46050076 0.46050076 0.25656319 0.0061891094 + 1200 81 0.39112377 0.39112377 0.21690744 0.0086559347 + 1300 81 0.33302801 0.33302801 0.19110222 0.0033381288 + 1400 81 0.39333146 0.39333146 0.21220965 0.0041348597 + 1500 81 0.35493951 0.35493951 0.19924958 0.00373736 + 1600 81 0.34154491 0.34154491 0.19031147 0.005349672 + 1700 100 0.25598828 0.25598828 0.14171498 0.0092236643 + 1800 100 0.2114074 0.2114074 0.12162965 0.0027213483 + 1900 100 0.21810423 0.21810423 0.12176698 0.0036436034 + 2000 100 0.2553198 0.2553198 0.13900087 0.0032844504 + 2100 100 0.24809937 0.24809937 0.13753654 0.0088764373 + 2200 100 0.22455642 0.22455642 0.12500977 0.0043517009 + 2300 100 0.19586874 0.19586874 0.11064996 0.0055178814 + 2400 100 0.059619074 0.059619074 0.045535036 0.00079051539 + 2500 100 0.052222462 0.052222462 0.038563852 0.00098981299 + 2600 100 0.036930777 0.036930777 0.027579114 0.0012285499 + 2700 100 0.027937818 0.027937818 0.020587353 0.00063085447 + 2800 100 0.02103783 0.02103783 0.015469157 0.00050316582 + 2900 100 0.010408128 0.010408128 0.0084894275 0.00035440391 + 3000 100 0.0077664382 0.0077664382 0.0068149074 0.0011153614 + 3100 100 0.0088789208 0.0088789208 0.0070143391 0.00032679783 + 3200 100 0.0077683432 0.0077683432 0.0059711038 0.00044762363 + 3300 100 0.00411 0.00411 0.00372409 0.00015328221 + 3400 100 0.0039192171 0.0039192171 0.0032409072 9.3603399e-05 + 3500 100 0.0023532199 0.0023532199 0.0020924799 0.00049044152 + 3600 100 0.0022544513 0.0022544513 0.0019545724 8.1086108e-05 + 3700 100 0.0012696379 0.0012696379 0.0013134108 5.0058058e-05 + 3800 100 0.0012035225 0.0012035225 0.0012490584 6.0331967e-05 + 3900 100 0.00080361803 0.00080361803 0.00094424552 6.7229227e-05 + 4000 100 0.00060715659 0.00060715659 0.00076521759 6.7029916e-05 + 4100 100 0.00058510487 0.00058510487 0.00073844578 5.5867098e-05 + 4200 100 0.00046832309 0.00046832309 0.00060848748 5.3853715e-05 + 4300 100 0.00045207186 0.00045207186 0.00057825336 4.8367831e-05 + 4400 100 0.00041874845 0.00041874845 0.00053103589 8.666037e-05 + 4500 100 0.00041136295 0.00041136295 0.00052246056 6.0456585e-05 + 4600 100 0.00041021147 0.00041021147 0.0005190668 4.8701604e-05 + 4700 100 0.00037176253 0.00037176253 0.00049156279 5.8874891e-05 + 4800 100 0.0003262417 0.0003262417 0.00045551846 5.0610728e-05 + 4900 100 0.00028093583 0.00028093583 0.00042099654 4.6558605e-05 + 5000 100 0.00027730599 0.00027730599 0.00041664922 4.7053044e-05 +Loop time of 0.081454 on 1 procs for 5000 steps with 100 atoms + +Performance: 26518022.146 tau/day, 61384.311 timesteps/s +99.4% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.0085223 | 0.0085223 | 0.0085223 | 0.0 | 10.46 +Neigh | 0.01466 | 0.01466 | 0.01466 | 0.0 | 18.00 +Comm | 0.00076532 | 0.00076532 | 0.00076532 | 0.0 | 0.94 +Output | 0.00052285 | 0.00052285 | 0.00052285 | 0.0 | 0.64 +Modify | 0.05317 | 0.05317 | 0.05317 | 0.0 | 65.28 +Other | | 0.003814 | | | 4.68 + +Nlocal: 100 ave 100 max 100 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 0 ave 0 max 0 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 158 ave 158 max 158 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 158 +Ave neighs/atom = 1.58 +Neighbor list builds = 306 +Dangerous builds = 0 + +region container delete +variable theta equal (step-5000)*(4.0*PI/5000) +region container block -6 6 -6 6 -6 6 units box rotate v_theta 0 0 0 0 0 1 +run 5000 +Memory usage per processor = 5.26337 Mbytes +Step Atoms Temp c_1 c_2 Press + 5000 100 0.00027730599 0.00027730599 0.00041664922 4.705763e-05 + 5100 100 0.60717077 0.60717077 0.33118944 0.010686501 + 5200 100 0.64991179 0.64991179 0.35498767 0.011370453 + 5300 100 0.72038713 0.72038713 0.38745069 0.010507667 + 5400 100 0.81357499 0.81357499 0.42946808 0.012920419 + 5500 100 0.90488411 0.90488411 0.46803321 0.015077428 + 5600 100 0.99065617 0.99065617 0.50811954 0.015556572 + 5700 100 1.0701203 1.0701203 0.54641187 0.016464366 + 5800 100 1.1351242 1.1351242 0.57607707 0.017832476 + 5900 100 1.1883602 1.1883602 0.60022389 0.019571838 + 6000 100 1.2153421 1.2153421 0.61245652 0.020549414 + 6100 100 1.2369293 1.2369293 0.62229634 0.01827529 + 6200 100 1.2556883 1.2556883 0.63207905 0.020286322 + 6300 100 1.2618555 1.2618555 0.63610311 0.019844583 + 6400 100 1.2671678 1.2671678 0.63873131 0.019817249 + 6500 100 1.2875312 1.2875312 0.64728693 0.020097362 + 6600 100 1.3014055 1.3014055 0.65413071 0.020000886 + 6700 100 1.2904021 1.2904021 0.6485358 0.020009625 + 6800 100 1.2962767 1.2962767 0.65088367 0.021340143 + 6900 100 1.3056081 1.3056081 0.65490644 0.020455771 + 7000 100 1.3116731 1.3116731 0.65766216 0.020475061 + 7100 100 1.319457 1.319457 0.66105016 0.020937651 + 7200 100 1.3213585 1.3213585 0.66207982 0.02120792 + 7300 100 1.3232411 1.3232411 0.66392391 0.021040683 + 7400 100 1.3300163 1.3300163 0.66599805 0.021202273 + 7500 100 1.3350122 1.3350122 0.66894534 0.021161833 + 7600 100 1.3344633 1.3344633 0.6688403 0.020871936 + 7700 100 1.3492825 1.3492825 0.6751371 0.021415859 + 7800 100 1.3539647 1.3539647 0.67757279 0.021306442 + 7900 100 1.3527157 1.3527157 0.67722774 0.021793531 + 8000 100 1.3526931 1.3526931 0.67713399 0.022973395 + 8100 100 1.3568279 1.3568279 0.67936578 0.021422428 + 8200 100 1.3599258 1.3599258 0.68113142 0.021397012 + 8300 100 1.3601893 1.3601893 0.68165656 0.021643375 + 8400 100 1.3752164 1.3752164 0.68788213 0.022208765 + 8500 100 1.3821458 1.3821458 0.69165274 0.022015877 + 8600 100 1.3784691 1.3784691 0.68964478 0.022144188 + 8700 100 1.3801422 1.3801422 0.6904093 0.0220402 + 8800 100 1.3900051 1.3900051 0.6947875 0.02216362 + 8900 100 1.3897902 1.3897902 0.69427134 0.023078569 + 9000 100 1.3909918 1.3909918 0.69456955 0.022043699 + 9100 100 1.3925028 1.3925028 0.69519141 0.022180156 + 9200 100 1.3923277 1.3923277 0.69512657 0.022113729 + 9300 100 1.3945193 1.3945193 0.69625374 0.022344694 + 9400 100 1.3960782 1.3960782 0.69705144 0.022181158 + 9500 100 1.3932407 1.3932407 0.69560365 0.022129998 + 9600 100 1.3925489 1.3925489 0.69532399 0.022124653 + 9700 100 1.3935299 1.3935299 0.69581607 0.022258368 + 9800 100 1.3933949 1.3933949 0.69579137 0.022209028 + 9900 100 1.3934712 1.3934712 0.69587898 0.022214942 + 10000 100 1.3935828 1.3935828 0.69598655 0.022231414 +Loop time of 0.261407 on 1 procs for 5000 steps with 100 atoms + +Performance: 8262972.563 tau/day, 19127.251 timesteps/s +99.8% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.042233 | 0.042233 | 0.042233 | 0.0 | 16.16 +Neigh | 0.035131 | 0.035131 | 0.035131 | 0.0 | 13.44 +Comm | 0.0010462 | 0.0010462 | 0.0010462 | 0.0 | 0.40 +Output | 0.00051785 | 0.00051785 | 0.00051785 | 0.0 | 0.20 +Modify | 0.17687 | 0.17687 | 0.17687 | 0.0 | 67.66 +Other | | 0.00561 | | | 2.15 + +Nlocal: 100 ave 100 max 100 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 0 ave 0 max 0 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 187 ave 187 max 187 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 187 +Ave neighs/atom = 1.87 +Neighbor list builds = 634 +Dangerous builds = 0 + +region container delete +region container block -6 6 -6 6 -6 6 units box +run 5000 +Memory usage per processor = 5.26337 Mbytes +Step Atoms Temp c_1 c_2 Press + 10000 100 1.3935828 1.3935828 0.69598655 0.02230659 + 10100 100 0.3402861 0.3402861 0.19584226 0.014767914 + 10200 100 0.19064555 0.19064555 0.12536788 0.0025413789 + 10300 100 0.13281358 0.13281358 0.10275768 0.002843208 + 10400 100 0.10124671 0.10124671 0.077914135 0.0017745353 + 10500 100 0.082636734 0.082636734 0.063857622 0.001419336 + 10600 100 0.066744462 0.066744462 0.051927437 0.0010830674 + 10700 100 0.060778462 0.060778462 0.047461784 0.0011418844 + 10800 100 0.043437178 0.043437178 0.032805669 0.0017050393 + 10900 100 0.036483219 0.036483219 0.027387805 0.00086936813 + 11000 100 0.027639076 0.027639076 0.021221241 0.00054920607 + 11100 100 0.023614696 0.023614696 0.018445634 0.00058724552 + 11200 100 0.020103248 0.020103248 0.015933089 0.00072830275 + 11300 100 0.018645345 0.018645345 0.014559759 0.0002319388 + 11400 100 0.015499672 0.015499672 0.01248828 0.00036020862 + 11500 100 0.013421296 0.013421296 0.010743248 0.00043093929 + 11600 100 0.011214892 0.011214892 0.0089653924 0.00059789544 + 11700 100 0.0086660806 0.0086660806 0.0070563902 0.00029684573 + 11800 100 0.0064777244 0.0064777244 0.0052946156 0.00046466386 + 11900 100 0.0059360881 0.0059360881 0.0048568813 8.361561e-05 + 12000 100 0.0045341025 0.0045341025 0.003883229 0.00016408047 + 12100 100 0.0042504415 0.0042504415 0.0036944958 6.5005147e-05 + 12200 100 0.0041367637 0.0041367637 0.0035928232 7.3025698e-05 + 12300 100 0.0037700129 0.0037700129 0.003283398 6.381318e-05 + 12400 100 0.0033494476 0.0033494476 0.0029274495 4.7731105e-05 + 12500 100 0.0030903175 0.0030903175 0.0027068073 6.797313e-05 + 12600 100 0.0026406999 0.0026406999 0.0023315387 0.0002371331 + 12700 100 0.0025020713 0.0025020713 0.0022367855 4.2787276e-05 + 12800 100 0.0022977381 0.0022977381 0.0020778307 3.9744567e-05 + 12900 100 0.002039634 0.002039634 0.0018862012 0.00011669223 + 13000 100 0.0018044702 0.0018044702 0.00171399 0.00013835538 + 13100 100 0.0016600965 0.0016600965 0.0015553191 3.2320019e-05 + 13200 100 0.0015596204 0.0015596204 0.001486374 1.9246911e-05 + 13300 100 0.001316505 0.001316505 0.0012105249 9.1469679e-05 + 13400 100 0.0012517536 0.0012517536 0.0011525753 4.815292e-05 + 13500 100 0.0010827608 0.0010827608 0.001038339 2.0913017e-05 + 13600 100 0.0009863908 0.0009863908 0.00095924929 9.7716736e-05 + 13700 100 0.00094543599 0.00094543599 0.00092425645 1.378887e-05 + 13800 100 0.00087893271 0.00087893271 0.00086801608 1.8981177e-05 + 13900 100 0.00080241572 0.00080241572 0.0007930026 5.0987122e-05 + 14000 100 0.00070705631 0.00070705631 0.00069238137 1.2900066e-05 + 14100 100 0.0006525032 0.0006525032 0.000637991 0.00010838464 + 14200 100 0.00059338444 0.00059338444 0.00057560454 7.3431324e-06 + 14300 100 0.00058641228 0.00058641228 0.00056944735 7.256852e-06 + 14400 100 0.00056221112 0.00056221112 0.00054625666 8.1343426e-06 + 14500 100 0.00055493127 0.00055493127 0.00053957583 1.1713058e-05 + 14600 100 0.00052854921 0.00052854921 0.00051816618 8.6527225e-06 + 14700 100 0.00052630581 0.00052630581 0.00051584277 6.4890475e-06 + 14800 100 0.00052563819 0.00052563819 0.00051493123 1.2687153e-05 + 14900 100 0.00052131364 0.00052131364 0.00050917244 7.4589995e-08 + 15000 100 0.00051902191 0.00051902191 0.00050725364 6.4228962e-06 +Loop time of 0.0895741 on 1 procs for 5000 steps with 100 atoms + +Performance: 24114113.723 tau/day, 55819.708 timesteps/s +99.3% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.0098987 | 0.0098987 | 0.0098987 | 0.0 | 11.05 +Neigh | 0.0061045 | 0.0061045 | 0.0061045 | 0.0 | 6.81 +Comm | 0.00069976 | 0.00069976 | 0.00069976 | 0.0 | 0.78 +Output | 0.00049758 | 0.00049758 | 0.00049758 | 0.0 | 0.56 +Modify | 0.068435 | 0.068435 | 0.068435 | 0.0 | 76.40 +Other | | 0.003939 | | | 4.40 + +Nlocal: 100 ave 100 max 100 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 0 ave 0 max 0 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 160 ave 160 max 160 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 160 +Ave neighs/atom = 1.6 +Neighbor list builds = 111 +Dangerous builds = 0 + +region container delete +variable theta equal (step-15000)*(4.0*PI/5000) +region container block -6 6 -6 6 -6 6 units box rotate v_theta 0 0 0 1 1 1 +run 5000 +Memory usage per processor = 5.26337 Mbytes +Step Atoms Temp c_1 c_2 Press + 15000 100 0.00051902191 0.00051902191 0.00050725364 6.4228962e-06 + 15100 100 1.1235353 1.1235353 0.72003773 0.013686681 + 15200 100 1.0778556 1.0778556 0.69137925 0.013478363 + 15300 100 1.069015 1.069015 0.69798184 0.014165255 + 15400 100 1.2249943 1.2249943 0.79096059 0.020933395 + 15500 100 1.5225664 1.5225664 0.94822282 0.023932611 + 15600 100 1.5867194 1.5867194 0.98143504 0.024565132 + 15700 100 1.6595267 1.6595267 1.0203985 0.025152432 + 15800 100 1.8188027 1.8188027 1.0857586 0.031597641 + 15900 100 1.9234102 1.9234102 1.1099361 0.032381895 + 16000 100 2.039435 2.039435 1.1656948 0.032501981 + 16100 100 2.17315 2.17315 1.2265552 0.032675825 + 16200 100 2.2017279 2.2017279 1.23995 0.028634878 + 16300 100 2.3510902 2.3510902 1.3055642 0.03248003 + 16400 100 2.373932 2.373932 1.3059254 0.031292969 + 16500 100 2.5010862 2.5010862 1.3607219 0.032322054 + 16600 100 2.4815092 2.4815092 1.3524159 0.031223889 + 16700 100 2.6549226 2.6549226 1.4383508 0.033713507 + 16800 100 2.8087564 2.8087564 1.5261538 0.036598837 + 16900 100 2.8653588 2.8653588 1.5649123 0.035890231 + 17000 100 2.903748 2.903748 1.5907716 0.038038745 + 17100 100 2.9679376 2.9679376 1.6195577 0.051771432 + 17200 100 2.9632377 2.9632377 1.6233074 0.039825751 + 17300 100 3.0436883 3.0436883 1.6591248 0.042862982 + 17400 100 3.0969015 3.0969015 1.6811582 0.042104811 + 17500 100 3.0827135 3.0827135 1.691414 0.045839327 + 17600 100 3.0854805 3.0854805 1.689399 0.041770144 + 17700 100 3.07523 3.07523 1.6685518 0.045104715 + 17800 100 2.9610899 2.9610899 1.6349099 0.039060791 + 17900 100 2.8002989 2.8002989 1.5665223 0.037917927 + 18000 100 2.9139644 2.9139644 1.6206891 0.050841302 + 18100 100 3.0134757 3.0134757 1.6673916 0.040967255 + 18200 100 3.0731184 3.0731184 1.6777507 0.043503474 + 18300 100 3.0915242 3.0915242 1.6843452 0.040157898 + 18400 100 3.098896 3.098896 1.6904524 0.039629218 + 18500 100 3.1651814 3.1651814 1.7290259 0.042604953 + 18600 100 3.353247 3.353247 1.8236992 0.045132486 + 18700 100 3.540156 3.540156 1.9078363 0.046602063 + 18800 100 3.6395129 3.6395129 1.9578976 0.045659959 + 18900 100 3.7638134 3.7638134 2.0179445 0.051061068 + 19000 100 3.7603453 3.7603453 2.003355 0.057123184 + 19100 100 3.9218495 3.9218495 2.0968869 0.057671742 + 19200 100 3.9924222 3.9924222 2.1321955 0.051824898 + 19300 100 3.9690887 3.9690887 2.1270643 0.054832867 + 19400 100 3.9408481 3.9408481 2.1146593 0.057020024 + 19500 100 3.8313782 3.8313782 2.0610797 0.055164704 + 19600 100 3.8317496 3.8317496 2.0668123 0.049840804 + 19700 100 3.6068628 3.6068628 1.964227 0.05142407 + 19800 100 3.5477437 3.5477437 1.9314948 0.051076014 + 19900 100 3.6526881 3.6526881 1.9855353 0.047130029 + 20000 100 3.7243709 3.7243709 2.0380212 0.048446835 +Loop time of 0.206397 on 1 procs for 5000 steps with 100 atoms + +Performance: 10465265.522 tau/day, 24225.152 timesteps/s +100.3% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.014297 | 0.014297 | 0.014297 | 0.0 | 6.93 +Neigh | 0.050213 | 0.050213 | 0.050213 | 0.0 | 24.33 +Comm | 0.0011115 | 0.0011115 | 0.0011115 | 0.0 | 0.54 +Output | 0.00051141 | 0.00051141 | 0.00051141 | 0.0 | 0.25 +Modify | 0.13415 | 0.13415 | 0.13415 | 0.0 | 65.00 +Other | | 0.006114 | | | 2.96 + +Nlocal: 100 ave 100 max 100 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 0 ave 0 max 0 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 142 ave 142 max 142 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 142 +Ave neighs/atom = 1.42 +Neighbor list builds = 899 +Dangerous builds = 0 + +region container delete +region container block -6 6 -6 6 -6 6 units box +run 5000 +Memory usage per processor = 5.26337 Mbytes +Step Atoms Temp c_1 c_2 Press + 20000 100 3.7243709 3.7243709 2.0380212 0.048156434 + 20100 100 1.1186527 1.1186527 0.69104385 0.014964891 + 20200 100 0.91445605 0.91445605 0.57005236 0.011324474 + 20300 100 0.8936601 0.8936601 0.55534411 0.011071843 + 20400 100 0.90773143 0.90773143 0.55999953 0.011254101 + 20500 100 0.91995508 0.91995508 0.55837916 0.011548541 + 20600 100 0.91682167 0.91682167 0.54095261 0.012563797 + 20700 100 0.97806337 0.97806337 0.56016442 0.012396925 + 20800 100 0.97778738 0.97778738 0.55606194 0.015441479 + 20900 100 0.77253213 0.77253213 0.44636799 0.011428992 + 21000 100 0.63053468 0.63053468 0.35995394 0.01005502 + 21100 100 0.25437539 0.25437539 0.16544433 0.004628738 + 21200 100 0.11828032 0.11828032 0.087911985 0.0037076362 + 21300 100 0.11219312 0.11219312 0.080957112 0.0015847347 + 21400 100 0.10765357 0.10765357 0.074676159 0.0022823419 + 21500 100 0.060787093 0.060787093 0.046135213 0.00091422949 + 21600 100 0.040447932 0.040447932 0.033050575 0.0013404194 + 21700 100 0.035227782 0.035227782 0.02916621 0.00138779 + 21800 100 0.03309101 0.03309101 0.026613861 0.00058184323 + 21900 100 0.031461843 0.031461843 0.024751985 0.0013090333 + 22000 100 0.021624144 0.021624144 0.017872639 0.0010893822 + 22100 100 0.016728267 0.016728267 0.01403934 0.00049128736 + 22200 100 0.016256915 0.016256915 0.013763903 0.00047288638 + 22300 100 0.01349256 0.01349256 0.011498343 0.0013508309 + 22400 100 0.010027007 0.010027007 0.0087924966 0.00030117996 + 22500 100 0.0107355 0.0107355 0.0088715062 0.001043188 + 22600 100 0.0095852245 0.0095852245 0.007965421 0.00028464236 + 22700 100 0.0072956464 0.0072956464 0.0062403843 0.00061636772 + 22800 100 0.0060874415 0.0060874415 0.0054788049 0.00021135824 + 22900 100 0.0059688159 0.0059688159 0.0049530273 0.00022094116 + 23000 100 0.0050218996 0.0050218996 0.0043518404 0.00022527705 + 23100 100 0.005022208 0.005022208 0.0043118432 0.00052482006 + 23200 100 0.0047096056 0.0047096056 0.0039698638 0.00026423471 + 23300 100 0.0039510068 0.0039510068 0.0034773285 0.0001891104 + 23400 100 0.0037308781 0.0037308781 0.0031763304 0.00027163016 + 23500 100 0.0036278619 0.0036278619 0.0030371899 0.00017961072 + 23600 100 0.0033598677 0.0033598677 0.0027586323 0.00015034494 + 23700 100 0.0028530843 0.0028530843 0.0024809444 0.00012294415 + 23800 100 0.0025388819 0.0025388819 0.0022812799 0.00018946676 + 23900 100 0.0021129272 0.0021129272 0.0019905358 0.00015816903 + 24000 100 0.0021010978 0.0021010978 0.0019864539 0.00017086049 + 24100 100 0.0022189886 0.0022189886 0.0020466911 0.00030932562 + 24200 100 0.0019226314 0.0019226314 0.0017933042 9.3246067e-05 + 24300 100 0.0016875781 0.0016875781 0.0015999656 9.9935458e-05 + 24400 100 0.0015929611 0.0015929611 0.001531011 9.7429139e-05 + 24500 100 0.0015143044 0.0015143044 0.0014044175 9.807117e-05 + 24600 100 0.0018595492 0.0018595492 0.0014740944 7.4734729e-05 + 24700 100 0.0011646988 0.0011646988 0.0010881356 6.1197025e-05 + 24800 100 0.0014641612 0.0014641612 0.0012316664 8.81462e-05 + 24900 100 0.001024996 0.001024996 0.00094311114 5.8776472e-05 + 25000 100 0.00097890442 0.00097890442 0.00090302317 3.3980657e-05 +Loop time of 0.0954661 on 1 procs for 5000 steps with 100 atoms + +Performance: 22625823.872 tau/day, 52374.592 timesteps/s +99.5% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.01234 | 0.01234 | 0.01234 | 0.0 | 12.93 +Neigh | 0.015404 | 0.015404 | 0.015404 | 0.0 | 16.14 +Comm | 0.00077391 | 0.00077391 | 0.00077391 | 0.0 | 0.81 +Output | 0.000494 | 0.000494 | 0.000494 | 0.0 | 0.52 +Modify | 0.062222 | 0.062222 | 0.062222 | 0.0 | 65.18 +Other | | 0.004233 | | | 4.43 + +Nlocal: 100 ave 100 max 100 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 0 ave 0 max 0 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 150 ave 150 max 150 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 150 +Ave neighs/atom = 1.5 +Neighbor list builds = 283 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/granregion/log.6Oct16.granregion.box.g++.4 b/examples/granregion/log.6Oct16.granregion.box.g++.4 new file mode 100644 index 000000000..daaae2019 --- /dev/null +++ b/examples/granregion/log.6Oct16.granregion.box.g++.4 @@ -0,0 +1,468 @@ +LAMMPS (5 Oct 2016) +# pouring spheres into container box + +units lj +atom_style sphere +boundary f f f +dimension 3 +comm_modify vel yes + +region box block -10 10 -10 10 -10 10 units box +create_box 2 box +Created orthogonal box = (-10 -10 -10) to (10 10 10) + 1 by 2 by 2 MPI processor grid + +pair_style hybrid gran/hooke 4000.0 NULL 100.0 NULL 0.5 1 +pair_coeff * * gran/hooke + +region container block -6 6 -6 6 -6 6 units box +fix container all wall/gran/region hooke/history 4000.0 NULL 100.0 NULL 0.5 1 region container + +neighbor 0.3 bin +neigh_modify delay 0 every 1 check yes + +fix 2 all nve/sphere +fix 3 all gravity 1.0 vector 0 0 -1 + +region slab block -2 2 -2 2 -2 2 units box +fix ins all pour 100 2 4767548 vol 0.4 10 diam one 1.0 region slab ignore +Particle insertion: 48 every 566 steps, 100 by step 1133 + +timestep 0.005 + +compute 1 all temp +compute_modify 1 dynamic yes + +compute 2 all temp/sphere +compute_modify 2 dynamic yes + +thermo 100 +thermo_style custom step atoms temp c_1 c_2 press +thermo_modify lost ignore +compute_modify thermo_temp dynamic yes + +#dump 2 all image 100 image.*.jpg type type # zoom 1.4 adiam 1.0 box no 0.0 axes yes 0.9 0.03 +#dump_modify 2 pad 5 + +run 5000 +Neighbor list info ... + 1 neighbor list requests + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 1.3 + ghost atom cutoff = 1.3 + binsize = 0.65 -> bins = 31 31 31 +Memory usage per processor = 0.0990257 Mbytes +Step Atoms Temp c_1 c_2 Press + 0 0 0 0 0 0 + 100 21 0.54270729 0.54270729 0.26473526 0.0013567682 + 200 21 0.87606961 0.87606961 0.42735103 0.002190174 + 300 21 1.1428374 1.1428374 0.55748167 0.0028570936 + 400 21 1.3543103 1.3543103 0.66829516 0.0033857758 + 500 21 1.0677786 1.0677786 0.53582407 0.0045048164 + 600 56 0.6744286 0.6744286 0.3502938 0.0047464584 + 700 56 0.75569283 0.75569283 0.39779462 0.0051953882 + 800 56 0.61597505 0.61597505 0.32943642 0.0086022783 + 900 56 0.65260802 0.65260802 0.34474044 0.0059298996 + 1000 56 0.51624952 0.51624952 0.28326898 0.0067827337 + 1100 56 0.46050076 0.46050076 0.25656319 0.0061891094 + 1200 81 0.39112377 0.39112377 0.21690744 0.0086559347 + 1300 81 0.33302801 0.33302801 0.19110222 0.0033381288 + 1400 81 0.39333146 0.39333146 0.21220965 0.0041348597 + 1500 81 0.35493951 0.35493951 0.19924958 0.00373736 + 1600 81 0.34154491 0.34154491 0.19031147 0.005349672 + 1700 100 0.25598828 0.25598828 0.14171498 0.0092236643 + 1800 100 0.2114074 0.2114074 0.12162965 0.0027213483 + 1900 100 0.21810423 0.21810423 0.12176698 0.0036436054 + 2000 100 0.2553198 0.2553198 0.13900087 0.0032844518 + 2100 100 0.24809936 0.24809936 0.13753654 0.0088764777 + 2200 100 0.22455625 0.22455625 0.12500973 0.0043515755 + 2300 100 0.19586871 0.19586871 0.11064996 0.0055176298 + 2400 100 0.059621411 0.059621411 0.045535517 0.00079910861 + 2500 100 0.052217518 0.052217518 0.038542594 0.0009759424 + 2600 100 0.036907358 0.036907358 0.027550263 0.0014047668 + 2700 100 0.027926944 0.027926944 0.020599405 0.00063362027 + 2800 100 0.020876282 0.020876282 0.015385856 0.00066161626 + 2900 100 0.010390963 0.010390963 0.0085038611 0.00026222195 + 3000 100 0.0080105974 0.0080105974 0.006995365 0.00059521652 + 3100 100 0.0087388005 0.0087388005 0.0069051613 0.00028045343 + 3200 100 0.0078828927 0.0078828927 0.0060159861 0.00014819289 + 3300 100 0.0039336821 0.0039336821 0.0036525886 0.0001439482 + 3400 100 0.0037684472 0.0037684472 0.0031531439 0.00010653386 + 3500 100 0.0023527874 0.0023527874 0.0020983632 6.3797052e-05 + 3600 100 0.0018768162 0.0018768162 0.0017248798 0.00014904114 + 3700 100 0.00135595 0.00135595 0.0013962044 6.2461444e-05 + 3800 100 0.0012673777 0.0012673777 0.0013074364 0.00028034063 + 3900 100 0.00081311806 0.00081311806 0.00095642595 7.9543605e-05 + 4000 100 0.00059774673 0.00059774673 0.00074849615 6.8190201e-05 + 4100 100 0.00052811986 0.00052811986 0.00067263919 5.012633e-05 + 4200 100 0.00049555855 0.00049555855 0.00061736675 4.9888372e-05 + 4300 100 0.00048274473 0.00048274473 0.00059050389 5.1381757e-05 + 4400 100 0.00047341333 0.00047341333 0.00058083446 5.02623e-05 + 4500 100 0.00046792237 0.00046792237 0.00057416894 4.9019652e-05 + 4600 100 0.00046035378 0.00046035378 0.00056694823 6.0353699e-05 + 4700 100 0.00038114933 0.00038114933 0.0004980117 6.5173515e-05 + 4800 100 0.0003783967 0.0003783967 0.00049488428 4.8463898e-05 + 4900 100 0.00027940611 0.00027940611 0.00041517649 5.0979155e-05 + 5000 100 0.00026071989 0.00026071989 0.00040045214 5.151673e-05 +Loop time of 0.0799825 on 4 procs for 5000 steps with 100 atoms + +Performance: 27005901.076 tau/day, 62513.660 timesteps/s +96.6% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.00093961 | 0.0032012 | 0.0054553 | 3.8 | 4.00 +Neigh | 0.0032456 | 0.0046872 | 0.0061908 | 2.0 | 5.86 +Comm | 0.014328 | 0.02121 | 0.029619 | 4.7 | 26.52 +Output | 0.0011828 | 0.0014142 | 0.0015574 | 0.4 | 1.77 +Modify | 0.002455 | 0.013876 | 0.026567 | 9.6 | 17.35 +Other | | 0.03559 | | | 44.50 + +Nlocal: 25 ave 51 max 0 min +Histogram: 2 0 0 0 0 0 0 0 0 2 +Nghost: 4.75 ave 11 max 0 min +Histogram: 2 0 0 0 0 0 0 1 0 1 +Neighs: 39.5 ave 85 max 0 min +Histogram: 2 0 0 0 0 0 0 0 1 1 + +Total # of neighbors = 158 +Ave neighs/atom = 1.58 +Neighbor list builds = 305 +Dangerous builds = 0 + +region container delete +variable theta equal (step-5000)*(4.0*PI/5000) +region container block -6 6 -6 6 -6 6 units box rotate v_theta 0 0 0 0 0 1 +run 5000 +Memory usage per processor = 5.16122 Mbytes +Step Atoms Temp c_1 c_2 Press + 5000 100 0.00026071989 0.00026071989 0.00040045214 5.1497323e-05 + 5100 100 0.66352492 0.66352492 0.35750241 0.015948709 + 5200 100 0.6922229 0.6922229 0.37176131 0.011025479 + 5300 100 0.76307067 0.76307067 0.40325027 0.010979511 + 5400 100 0.83871418 0.83871418 0.43756084 0.012600965 + 5500 100 0.93090048 0.93090048 0.4817574 0.012306942 + 5600 100 0.98338567 0.98338567 0.50374148 0.015434412 + 5700 100 1.0455442 1.0455442 0.53265847 0.017959409 + 5800 100 1.1081511 1.1081511 0.56112842 0.018832417 + 5900 100 1.1724309 1.1724309 0.59276447 0.019257973 + 6000 100 1.1914813 1.1914813 0.60201665 0.019694573 + 6100 100 1.2417733 1.2417733 0.62578893 0.019616524 + 6200 100 1.2612898 1.2612898 0.63503847 0.020442394 + 6300 100 1.2657345 1.2657345 0.63714395 0.020498843 + 6400 100 1.2678009 1.2678009 0.63828941 0.019900919 + 6500 100 1.284156 1.284156 0.64724666 0.020147256 + 6600 100 1.3090278 1.3090278 0.65925035 0.02136883 + 6700 100 1.3122075 1.3122075 0.66136807 0.020782325 + 6800 100 1.3147107 1.3147107 0.66026206 0.022887611 + 6900 100 1.3185295 1.3185295 0.66157265 0.021249838 + 7000 100 1.3232771 1.3232771 0.66334852 0.021738995 + 7100 100 1.3375003 1.3375003 0.67017176 0.021997185 + 7200 100 1.3349835 1.3349835 0.66895884 0.022149977 + 7300 100 1.3388711 1.3388711 0.67061163 0.021662545 + 7400 100 1.338676 1.338676 0.67074642 0.021076102 + 7500 100 1.3409052 1.3409052 0.67205098 0.021664853 + 7600 100 1.3499236 1.3499236 0.67612412 0.021653422 + 7700 100 1.3479719 1.3479719 0.67510646 0.021873569 + 7800 100 1.3489138 1.3489138 0.67563223 0.021419315 + 7900 100 1.357018 1.357018 0.6795804 0.022201202 + 8000 100 1.3540513 1.3540513 0.67843711 0.02275761 + 8100 100 1.3560429 1.3560429 0.67947065 0.022421723 + 8200 100 1.3590694 1.3590694 0.6806094 0.022004213 + 8300 100 1.3592154 1.3592154 0.68083948 0.021923269 + 8400 100 1.3601392 1.3601392 0.68121418 0.022155184 + 8500 100 1.3622149 1.3622149 0.6824182 0.022126924 + 8600 100 1.3651697 1.3651697 0.68397342 0.022195287 + 8700 100 1.3679254 1.3679254 0.68540978 0.023609651 + 8800 100 1.3686254 1.3686254 0.68559712 0.02242291 + 8900 100 1.3761277 1.3761277 0.68897201 0.023594162 + 9000 100 1.379968 1.379968 0.69045216 0.022516846 + 9100 100 1.3784732 1.3784732 0.68955121 0.022836115 + 9200 100 1.376848 1.376848 0.6885551 0.02279321 + 9300 100 1.3799231 1.3799231 0.68964009 0.023105818 + 9400 100 1.3817992 1.3817992 0.69057466 0.023062265 + 9500 100 1.3836544 1.3836544 0.69156755 0.024363244 + 9600 100 1.388032 1.388032 0.69348762 0.024930983 + 9700 100 1.3943738 1.3943738 0.6965703 0.024448451 + 9800 100 1.3963094 1.3963094 0.6971039 0.02341203 + 9900 100 1.3995489 1.3995489 0.69881652 0.023502542 + 10000 100 1.3974742 1.3974742 0.69765474 0.02340004 +Loop time of 0.18267 on 4 procs for 5000 steps with 100 atoms + +Performance: 11824571.055 tau/day, 27371.692 timesteps/s +99.1% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.0010765 | 0.012038 | 0.023519 | 9.9 | 6.59 +Neigh | 0.0057316 | 0.010541 | 0.015351 | 4.6 | 5.77 +Comm | 0.0067229 | 0.017007 | 0.028509 | 7.8 | 9.31 +Output | 0.0011928 | 0.002021 | 0.0027668 | 1.6 | 1.11 +Modify | 0.009697 | 0.053707 | 0.098413 | 19.0 | 29.40 +Other | | 0.08736 | | | 47.82 + +Nlocal: 25 ave 51 max 0 min +Histogram: 2 0 0 0 0 0 0 0 0 2 +Nghost: 3.25 ave 8 max 0 min +Histogram: 2 0 0 0 0 0 1 0 0 1 +Neighs: 46.75 ave 104 max 0 min +Histogram: 2 0 0 0 0 0 0 1 0 1 + +Total # of neighbors = 187 +Ave neighs/atom = 1.87 +Neighbor list builds = 633 +Dangerous builds = 0 + +region container delete +region container block -6 6 -6 6 -6 6 units box +run 5000 +Memory usage per processor = 5.16122 Mbytes +Step Atoms Temp c_1 c_2 Press + 10000 100 1.3974742 1.3974742 0.69765474 0.023347613 + 10100 100 0.34944285 0.34944285 0.20251378 0.019176827 + 10200 100 0.22524385 0.22524385 0.14368424 0.0033260831 + 10300 100 0.15243438 0.15243438 0.11070165 0.0064816535 + 10400 100 0.1143586 0.1143586 0.087867032 0.0024091961 + 10500 100 0.092025102 0.092025102 0.071291506 0.0030683413 + 10600 100 0.071051442 0.071051442 0.05700858 0.00100243 + 10700 100 0.058346771 0.058346771 0.04843626 0.0006073275 + 10800 100 0.048700232 0.048700232 0.039550383 0.00091511006 + 10900 100 0.036880936 0.036880936 0.029482183 0.0011698854 + 11000 100 0.028768807 0.028768807 0.023865852 0.0011980794 + 11100 100 0.022823005 0.022823005 0.018819891 0.0004639259 + 11200 100 0.016954703 0.016954703 0.014075803 0.00085142865 + 11300 100 0.015359685 0.015359685 0.01295219 0.00026241662 + 11400 100 0.012748378 0.012748378 0.011085291 0.00045626939 + 11500 100 0.010464459 0.010464459 0.0087024732 0.00029325411 + 11600 100 0.0099186727 0.0099186727 0.0080127406 0.00031388584 + 11700 100 0.0088308874 0.0088308874 0.0072317369 0.00017850972 + 11800 100 0.0081740195 0.0081740195 0.0066522963 0.00012282618 + 11900 100 0.0079005289 0.0079005289 0.0063346391 0.00010630403 + 12000 100 0.0066277573 0.0066277573 0.0054122601 5.4791661e-05 + 12100 100 0.00567928 0.00567928 0.0047331385 9.2668647e-05 + 12200 100 0.005282803 0.005282803 0.0043827202 8.7820361e-05 + 12300 100 0.0051590302 0.0051590302 0.0042806737 6.5433983e-05 + 12400 100 0.0049013329 0.0049013329 0.0040882737 6.2007733e-05 + 12500 100 0.0044725745 0.0044725745 0.0037535523 6.1132729e-05 + 12600 100 0.0043131884 0.0043131884 0.0035845765 5.3375706e-05 + 12700 100 0.0042020236 0.0042020236 0.0034902096 0.0001192142 + 12800 100 0.0041367453 0.0041367453 0.003433341 0.00011052418 + 12900 100 0.0039862367 0.0039862367 0.0033026224 5.2674711e-05 + 13000 100 0.0033163769 0.0033163769 0.0028118123 5.9042575e-05 + 13100 100 0.0030645983 0.0030645983 0.002571872 4.9521551e-05 + 13200 100 0.002808301 0.002808301 0.0023652684 3.4748246e-05 + 13300 100 0.002556475 0.002556475 0.0021699595 0.00042840611 + 13400 100 0.0023430405 0.0023430405 0.0019913198 2.2687303e-05 + 13500 100 0.0021422817 0.0021422817 0.0018017112 -6.7761855e-06 + 13600 100 0.0020993702 0.0020993702 0.001749657 2.5979707e-05 + 13700 100 0.0019871396 0.0019871396 0.0016647634 5.754995e-05 + 13800 100 0.0017311886 0.0017311886 0.0014696399 2.1585018e-05 + 13900 100 0.0016249641 0.0016249641 0.0013982224 2.0108931e-05 + 14000 100 0.0015874763 0.0015874763 0.0013613318 0.00018348921 + 14100 100 0.0013772541 0.0013772541 0.0012193388 1.9336869e-05 + 14200 100 0.0013587865 0.0013587865 0.0012054213 1.807845e-05 + 14300 100 0.0011824329 0.0011824329 0.0010348168 0.00017307518 + 14400 100 0.0011387278 0.0011387278 0.0010010725 1.4091757e-05 + 14500 100 0.0010441599 0.0010441599 0.00092205881 1.3630652e-05 + 14600 100 0.00096839518 0.00096839518 0.00086828535 1.2437299e-05 + 14700 100 0.00094215882 0.00094215882 0.00084418599 5.3989122e-05 + 14800 100 0.00077297853 0.00077297853 0.00070382005 8.5049867e-06 + 14900 100 0.00072181281 0.00072181281 0.00066110432 8.9324335e-06 + 15000 100 0.00070122327 0.00070122327 0.00063826734 3.4876262e-05 +Loop time of 0.0815294 on 4 procs for 5000 steps with 100 atoms + +Performance: 26493517.176 tau/day, 61327.586 timesteps/s +97.8% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.00076294 | 0.0033154 | 0.0062585 | 4.3 | 4.07 +Neigh | 0.0010953 | 0.0020078 | 0.002914 | 2.0 | 2.46 +Comm | 0.0021389 | 0.012184 | 0.023433 | 9.1 | 14.94 +Output | 0.0011332 | 0.0014591 | 0.0017147 | 0.7 | 1.79 +Modify | 0.00083971 | 0.017889 | 0.035367 | 12.7 | 21.94 +Other | | 0.04467 | | | 54.79 + +Nlocal: 25 ave 54 max 0 min +Histogram: 2 0 0 0 0 0 0 0 1 1 +Nghost: 3.75 ave 8 max 0 min +Histogram: 2 0 0 0 0 0 0 0 1 1 +Neighs: 37.5 ave 97 max 0 min +Histogram: 2 0 0 0 0 1 0 0 0 1 + +Total # of neighbors = 150 +Ave neighs/atom = 1.5 +Neighbor list builds = 120 +Dangerous builds = 0 + +region container delete +variable theta equal (step-15000)*(4.0*PI/5000) +region container block -6 6 -6 6 -6 6 units box rotate v_theta 0 0 0 1 1 1 +run 5000 +Memory usage per processor = 5.16122 Mbytes +Step Atoms Temp c_1 c_2 Press + 15000 100 0.00070122327 0.00070122327 0.00063826734 3.4742207e-05 + 15100 100 1.1981004 1.1981004 0.74046013 0.017300203 + 15200 100 1.2197457 1.2197457 0.75847511 0.016724637 + 15300 100 1.1794198 1.1794198 0.77076582 0.017228755 + 15400 100 1.4027714 1.4027714 0.87950036 0.021028602 + 15500 100 1.5514702 1.5514702 0.95040716 0.019935207 + 15600 100 1.8360404 1.8360404 1.0987247 0.02494663 + 15700 100 2.0317625 2.0317625 1.2004001 0.029286087 + 15800 100 2.0478625 2.0478625 1.189893 0.031660426 + 15900 100 2.1289888 2.1289888 1.2083316 0.028754408 + 16000 100 2.2261493 2.2261493 1.2550891 0.030665647 + 16100 100 2.3005184 2.3005184 1.29238 0.036511242 + 16200 100 2.4515818 2.4515818 1.3563253 0.033787104 + 16300 100 2.4524614 2.4524614 1.3571527 0.031905963 + 16400 100 2.5592541 2.5592541 1.405001 0.035688651 + 16500 100 2.5311864 2.5311864 1.3918694 0.032451265 + 16600 100 2.6471904 2.6471904 1.4481739 0.034763978 + 16700 100 2.7024085 2.7024085 1.4785065 0.037514299 + 16800 100 2.8116979 2.8116979 1.5403269 0.03585152 + 16900 100 2.9095374 2.9095374 1.5962283 0.038244982 + 17000 100 2.9228985 2.9228985 1.5978628 0.037971615 + 17100 100 2.983589 2.983589 1.6205713 0.038332341 + 17200 100 3.1245984 3.1245984 1.6925827 0.042532223 + 17300 100 3.1060575 3.1060575 1.6713928 0.052589575 + 17400 100 3.2494904 3.2494904 1.7567188 0.044783721 + 17500 100 3.2313349 3.2313349 1.7549177 0.044959213 + 17600 100 3.3928412 3.3928412 1.822978 0.052512199 + 17700 100 3.3064729 3.3064729 1.7924768 0.046624738 + 17800 100 3.1907518 3.1907518 1.7406131 0.042864325 + 17900 100 3.0224556 3.0224556 1.6641648 0.040151025 + 18000 100 3.105271 3.105271 1.7045599 0.047137803 + 18100 100 3.0293425 3.0293425 1.6626024 0.04198758 + 18200 100 3.139773 3.139773 1.7310307 0.040137164 + 18300 100 2.9732894 2.9732894 1.6555933 0.03777758 + 18400 100 3.1250324 3.1250324 1.739812 0.038542298 + 18500 100 3.1687407 3.1687407 1.7593494 0.041591022 + 18600 100 3.2880821 3.2880821 1.8169373 0.042503015 + 18700 100 3.4877047 3.4877047 1.9049979 0.048156272 + 18800 100 3.7982973 3.7982973 2.055323 0.049805341 + 18900 100 3.9922267 3.9922267 2.1260665 0.062688073 + 19000 100 3.8620284 3.8620284 2.0652184 0.064418518 + 19100 100 3.8757665 3.8757665 2.0615465 0.058600317 + 19200 100 3.9425495 3.9425495 2.1030375 0.053714175 + 19300 100 3.8589133 3.8589133 2.0485568 0.05531747 + 19400 100 3.9202395 3.9202395 2.0904529 0.056324297 + 19500 100 3.9748628 3.9748628 2.1114492 0.055590699 + 19600 100 3.8876771 3.8876771 2.0918436 0.052415532 + 19700 100 3.8975921 3.8975921 2.0755799 0.050647718 + 19800 100 3.7488333 3.7488333 2.0024562 0.056966734 + 19900 100 3.7818574 3.7818574 2.00915 0.050079148 + 20000 100 3.4510736 3.4510736 1.8525818 0.053548452 +Loop time of 0.156607 on 4 procs for 5000 steps with 100 atoms + +Performance: 13792452.627 tau/day, 31926.974 timesteps/s +98.5% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.0030923 | 0.0049732 | 0.0071678 | 2.1 | 3.18 +Neigh | 0.012225 | 0.015592 | 0.017859 | 1.7 | 9.96 +Comm | 0.034876 | 0.037526 | 0.040807 | 1.1 | 23.96 +Output | 0.0013812 | 0.0015668 | 0.0017419 | 0.3 | 1.00 +Modify | 0.026932 | 0.044011 | 0.054787 | 5.0 | 28.10 +Other | | 0.05294 | | | 33.80 + +Nlocal: 25 ave 41 max 12 min +Histogram: 1 0 0 1 1 0 0 0 0 1 +Nghost: 3.25 ave 6 max 1 min +Histogram: 1 0 1 0 0 0 1 0 0 1 +Neighs: 35.75 ave 59 max 9 min +Histogram: 1 0 0 0 0 1 1 0 0 1 + +Total # of neighbors = 143 +Ave neighs/atom = 1.43 +Neighbor list builds = 917 +Dangerous builds = 0 + +region container delete +region container block -6 6 -6 6 -6 6 units box +run 5000 +Memory usage per processor = 5.16122 Mbytes +Step Atoms Temp c_1 c_2 Press + 20000 100 3.4510736 3.4510736 1.8525818 0.053182767 + 20100 100 0.99241675 0.99241675 0.61590164 0.015233656 + 20200 100 0.92799489 0.92799489 0.55540992 0.011885237 + 20300 100 0.9171573 0.9171573 0.54477252 0.012926388 + 20400 100 0.86718407 0.86718407 0.5145422 0.011384414 + 20500 100 0.84470122 0.84470122 0.50181203 0.010482207 + 20600 100 0.93025469 0.93025469 0.53939952 0.011377044 + 20700 100 0.96631348 0.96631348 0.55772027 0.015287231 + 20800 100 0.90708015 0.90708015 0.52037018 0.014854537 + 20900 100 0.73319001 0.73319001 0.42824847 0.0092980012 + 21000 100 0.3371096 0.3371096 0.21272171 0.0061783554 + 21100 100 0.21771022 0.21771022 0.14128887 0.0082147558 + 21200 100 0.18133275 0.18133275 0.11945636 0.0055722731 + 21300 100 0.17117199 0.17117199 0.11048263 0.0027980106 + 21400 100 0.15741047 0.15741047 0.10346676 0.0023057723 + 21500 100 0.10045855 0.10045855 0.069905343 0.0023941181 + 21600 100 0.066094864 0.066094864 0.051285108 0.0022519002 + 21700 100 0.048622069 0.048622069 0.040662255 0.00073951939 + 21800 100 0.046829799 0.046829799 0.037431722 0.0015913976 + 21900 100 0.025308514 0.025308514 0.02092076 0.00064225773 + 22000 100 0.016326886 0.016326886 0.013588504 0.00087416572 + 22100 100 0.011892981 0.011892981 0.010417133 0.00080132313 + 22200 100 0.011974602 0.011974602 0.010342276 0.00044437732 + 22300 100 0.012567486 0.012567486 0.010294969 0.00048413872 + 22400 100 0.011676022 0.011676022 0.0091714238 0.00066567365 + 22500 100 0.0098737136 0.0098737136 0.0079252142 0.00024081335 + 22600 100 0.0052495523 0.0052495523 0.0047802341 0.00029167814 + 22700 100 0.0049396543 0.0049396543 0.0043570686 0.00019793167 + 22800 100 0.004469254 0.004469254 0.0038657445 0.00052965165 + 22900 100 0.0043837877 0.0043837877 0.0034611363 0.00045595698 + 23000 100 0.003439309 0.003439309 0.0028031344 0.00025784869 + 23100 100 0.0034805091 0.0034805091 0.0027537344 0.00012746906 + 23200 100 0.0045502061 0.0045502061 0.0032298328 0.00024006432 + 23300 100 0.0028553043 0.0028553043 0.0023107483 0.00012803066 + 23400 100 0.0022736412 0.0022736412 0.0018560302 0.0002706771 + 23500 100 0.0020966521 0.0020966521 0.0017106541 0.00014239612 + 23600 100 0.0018760993 0.0018760993 0.0015415318 0.00010892634 + 23700 100 0.0022362451 0.0022362451 0.0017014519 0.00012547256 + 23800 100 0.0017603403 0.0017603403 0.0014681398 0.00023372731 + 23900 100 0.0023396747 0.0023396747 0.0016700312 0.00017014305 + 24000 100 0.0012059144 0.0012059144 0.0009982224 3.6215959e-05 + 24100 100 0.0011739433 0.0011739433 0.00097155852 3.6169918e-05 + 24200 100 0.0011071139 0.0011071139 0.00092095478 8.8000847e-05 + 24300 100 0.0011078659 0.0011078659 0.00092073833 4.8706222e-05 + 24400 100 0.0011037562 0.0011037562 0.00091673546 3.7548502e-05 + 24500 100 0.00098422752 0.00098422752 0.00083054499 9.1151844e-05 + 24600 100 0.00097403646 0.00097403646 0.00082364881 5.0914687e-05 + 24700 100 0.00093082012 0.00093082012 0.00079047801 3.2230016e-05 + 24800 100 0.0009138973 0.0009138973 0.00075880177 2.8780789e-05 + 24900 100 0.0012881027 0.0012881027 0.00093025416 1.6385252e-05 + 25000 100 0.00076099168 0.00076099168 0.00065175575 9.417272e-06 +Loop time of 0.0846543 on 4 procs for 5000 steps with 100 atoms + +Performance: 25515528.493 tau/day, 59063.723 timesteps/s +98.9% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.0010469 | 0.0037468 | 0.0067947 | 4.3 | 4.43 +Neigh | 0.0032442 | 0.0047541 | 0.0065064 | 2.0 | 5.62 +Comm | 0.0085762 | 0.016923 | 0.024509 | 5.8 | 19.99 +Output | 0.0011523 | 0.0014572 | 0.0016789 | 0.6 | 1.72 +Modify | 0.0017715 | 0.016296 | 0.031399 | 11.1 | 19.25 +Other | | 0.04148 | | | 49.00 + +Nlocal: 25 ave 50 max 0 min +Histogram: 2 0 0 0 0 0 0 0 0 2 +Nghost: 6 ave 13 max 0 min +Histogram: 2 0 0 0 0 0 0 0 1 1 +Neighs: 39 ave 80 max 0 min +Histogram: 2 0 0 0 0 0 0 0 0 2 + +Total # of neighbors = 156 +Ave neighs/atom = 1.56 +Neighbor list builds = 284 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/granregion/log.6Oct16.granregion.funnel.g++.1 b/examples/granregion/log.6Oct16.granregion.funnel.g++.1 new file mode 100644 index 000000000..86faeb340 --- /dev/null +++ b/examples/granregion/log.6Oct16.granregion.funnel.g++.1 @@ -0,0 +1,608 @@ +LAMMPS (5 Oct 2016) +# pour particles into cone-shaped funnel, settle them, let them run out bottom + +variable name string funnel_pour + +thermo_modify flush yes +units si +variable PI equal 3.141592653589 +variable seed equal 14314 + +############################################### +# Geometry-related parameters +############################################### + +variable xlo equal 10 +variable xhi equal 40 +variable ylo equal 10 +variable yhi equal 40 +variable zlo equal -20 +variable zhi equal 50 + +variable xc equal 25 +variable yc equal 25 + +variable zconehi equal 50 +variable zconelo equal 10 +variable zcyllo equal 0 +variable radconelo equal 2 +variable radconehi equal 20 + +################################################ +# Particle sizes +################################################ + +variable rlo equal 0.25 +variable rhi equal 0.5 +variable dlo equal 2.0*${rlo} +variable dlo equal 2.0*0.25 +variable dhi equal 2.0*${rhi} +variable dhi equal 2.0*0.5 + +variable skin equal ${rhi} +variable skin equal 0.5 + +############################################### +# Granular contact parameters +############################################### + +variable coeffRes equal 0.1 +variable coeffFric equal 0.5 + +variable density equal 1.0 +variable EYoung equal 10^5 +variable Poisson equal 2.0/7.0 +variable GShear equal ${EYoung}/(2*(1+${Poisson})) +variable GShear equal 100000/(2*(1+${Poisson})) +variable GShear equal 100000/(2*(1+0.285714285714286)) + +variable gravity equal 1.0 + +variable reff equal 0.5*(${rhi}+${rlo}) +variable reff equal 0.5*(0.5+${rlo}) +variable reff equal 0.5*(0.5+0.25) +variable meff equal ${density}*4.0/3.0*${PI}*${reff}^3 +variable meff equal 1*4.0/3.0*${PI}*${reff}^3 +variable meff equal 1*4.0/3.0*3.141592653589*${reff}^3 +variable meff equal 1*4.0/3.0*3.141592653589*0.375^3 +variable min_mass equal ${density}*4.0/3.0*${PI}*${rlo}*${rlo}*${rlo} +variable min_mass equal 1*4.0/3.0*${PI}*${rlo}*${rlo}*${rlo} +variable min_mass equal 1*4.0/3.0*3.141592653589*${rlo}*${rlo}*${rlo} +variable min_mass equal 1*4.0/3.0*3.141592653589*0.25*${rlo}*${rlo} +variable min_mass equal 1*4.0/3.0*3.141592653589*0.25*0.25*${rlo} +variable min_mass equal 1*4.0/3.0*3.141592653589*0.25*0.25*0.25 +variable max_mass equal ${density}*4.0/3.0*${PI}*${rhi}*${rhi}*${rhi} +variable max_mass equal 1*4.0/3.0*${PI}*${rhi}*${rhi}*${rhi} +variable max_mass equal 1*4.0/3.0*3.141592653589*${rhi}*${rhi}*${rhi} +variable max_mass equal 1*4.0/3.0*3.141592653589*0.5*${rhi}*${rhi} +variable max_mass equal 1*4.0/3.0*3.141592653589*0.5*0.5*${rhi} +variable max_mass equal 1*4.0/3.0*3.141592653589*0.5*0.5*0.5 + +## Typical way to set kn, kt, etc.: +variable kn equal 4.0*${GShear}/(3*(1-${Poisson})) +variable kn equal 4.0*38888.8888888889/(3*(1-${Poisson})) +variable kn equal 4.0*38888.8888888889/(3*(1-0.285714285714286)) +variable kt equal 4.0*${GShear}/(2-${Poisson}) +variable kt equal 4.0*38888.8888888889/(2-${Poisson}) +variable kt equal 4.0*38888.8888888889/(2-0.285714285714286) + +variable a equal (-2.0*log(${coeffRes})/${PI})^2 +variable a equal (-2.0*log(0.1)/${PI})^2 +variable a equal (-2.0*log(0.1)/3.141592653589)^2 +variable gamma_n equal sqrt($a*2*${kn}/${min_mass}/(1+0.25*$a)) +variable gamma_n equal sqrt(0.405284734569556*2*${kn}/${min_mass}/(1+0.25*$a)) +variable gamma_n equal sqrt(0.405284734569556*2*72592.5925925926/${min_mass}/(1+0.25*$a)) +variable gamma_n equal sqrt(0.405284734569556*2*72592.5925925926/0.0654498469497708/(1+0.25*$a)) +variable gamma_n equal sqrt(0.405284734569556*2*72592.5925925926/0.0654498469497708/(1+0.25*0.405284734569556)) +variable gamma_t equal ${gamma_n}*0.5 +variable gamma_t equal 903.503751814138*0.5 + +variable tcol equal ${PI}/sqrt(2*${kn}/${min_mass}-${gamma_n}/4.0) +variable tcol equal 3.141592653589/sqrt(2*${kn}/${min_mass}-${gamma_n}/4.0) +variable tcol equal 3.141592653589/sqrt(2*72592.5925925926/${min_mass}-${gamma_n}/4.0) +variable tcol equal 3.141592653589/sqrt(2*72592.5925925926/0.0654498469497708-${gamma_n}/4.0) +variable tcol equal 3.141592653589/sqrt(2*72592.5925925926/0.0654498469497708-903.503751814138/4.0) + +variable dt equal ${tcol}*0.05 +variable dt equal 0.00210943016014969*0.05 +timestep ${dt} +timestep 0.000105471508007485 + +############################################### +variable dumpfreq equal 1000 +variable logfreq equal 1000 + +newton off +atom_style sphere + +boundary p p f + +region boxreg block ${xlo} ${xhi} ${ylo} ${yhi} ${zlo} ${zhi} +region boxreg block 10 ${xhi} ${ylo} ${yhi} ${zlo} ${zhi} +region boxreg block 10 40 ${ylo} ${yhi} ${zlo} ${zhi} +region boxreg block 10 40 10 ${yhi} ${zlo} ${zhi} +region boxreg block 10 40 10 40 ${zlo} ${zhi} +region boxreg block 10 40 10 40 -20 ${zhi} +region boxreg block 10 40 10 40 -20 50 +create_box 1 boxreg +Created orthogonal box = (10 10 -20) to (40 40 50) + 1 by 1 by 1 MPI processor grid + +pair_style gran/hertz/history ${kn} ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 +pair_style gran/hertz/history 72592.5925925926 ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 +pair_style gran/hertz/history 72592.5925925926 90740.7407407408 ${gamma_n} ${gamma_t} ${coeffFric} 1 +pair_style gran/hertz/history 72592.5925925926 90740.7407407408 903.503751814138 ${gamma_t} ${coeffFric} 1 +pair_style gran/hertz/history 72592.5925925926 90740.7407407408 903.503751814138 451.751875907069 ${coeffFric} 1 +pair_style gran/hertz/history 72592.5925925926 90740.7407407408 903.503751814138 451.751875907069 0.5 1 +pair_coeff * * + +neighbor ${skin} bin +neighbor 0.5 bin +thermo ${logfreq} +thermo 1000 + +comm_style brick +comm_modify mode multi group all vel yes +balance 1.1 shift xyz 20 1.1 +Neighbor list info ... + 2 neighbor list requests + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 0 + ghost atom cutoff = 0 + binsize = 30 -> bins = 1 1 3 +fix bal all balance 10000 1.1 shift xyz 20 1.01 + +####################### Options specific to pouring ######################### + +# insertion region for fix/pour + +region insreg cylinder z ${xc} ${yc} 10 30 50 side in units box +region insreg cylinder z 25 ${yc} 10 30 50 side in units box +region insreg cylinder z 25 25 10 30 50 side in units box + +# define cone and cylinder regions - see lammps doc on region command +# note new open options + +region cylreg cylinder z ${xc} ${yc} ${radconelo} ${zcyllo} ${zconelo} side in units box open 2 #Top is open +region cylreg cylinder z 25 ${yc} ${radconelo} ${zcyllo} ${zconelo} side in units box open 2 +region cylreg cylinder z 25 25 ${radconelo} ${zcyllo} ${zconelo} side in units box open 2 +region cylreg cylinder z 25 25 2 ${zcyllo} ${zconelo} side in units box open 2 +region cylreg cylinder z 25 25 2 0 ${zconelo} side in units box open 2 +region cylreg cylinder z 25 25 2 0 10 side in units box open 2 + +region conereg cone z ${xc} ${yc} ${radconelo} ${radconehi} ${zconelo} ${zconehi} side in units box open 1 open 2 #Bottom and top are open +region conereg cone z 25 ${yc} ${radconelo} ${radconehi} ${zconelo} ${zconehi} side in units box open 1 open 2 +region conereg cone z 25 25 ${radconelo} ${radconehi} ${zconelo} ${zconehi} side in units box open 1 open 2 +region conereg cone z 25 25 2 ${radconehi} ${zconelo} ${zconehi} side in units box open 1 open 2 +region conereg cone z 25 25 2 20 ${zconelo} ${zconehi} side in units box open 1 open 2 +region conereg cone z 25 25 2 20 10 ${zconehi} side in units box open 1 open 2 +region conereg cone z 25 25 2 20 10 50 side in units box open 1 open 2 + +region hopreg union 2 conereg cylreg + +fix grav all gravity ${gravity} vector 0 0 -1 +fix grav all gravity 1 vector 0 0 -1 +fix 1 all nve/sphere + + +fix hopper3 all wall/gran/region hertz/history ${kn} ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 90740.7407407408 ${gamma_n} ${gamma_t} ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 90740.7407407408 903.503751814138 ${gamma_t} ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 90740.7407407408 903.503751814138 451.751875907069 ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 90740.7407407408 903.503751814138 451.751875907069 0.5 1 region hopreg + +fix ins all pour 2000 1 42424 region insreg diam range ${dlo} ${dhi} dens ${density} ${density} +fix ins all pour 2000 1 42424 region insreg diam range 0.5 ${dhi} dens ${density} ${density} +fix ins all pour 2000 1 42424 region insreg diam range 0.5 1 dens ${density} ${density} +fix ins all pour 2000 1 42424 region insreg diam range 0.5 1 dens 1 ${density} +fix ins all pour 2000 1 42424 region insreg diam range 0.5 1 dens 1 1 +Particle insertion: 3000 every 59965 steps, 2000 by step 1 + +#dump 1 all custom ${dumpfreq} ${name}.dump # id type mass diameter x y z + +#dump 2 all image 4000 image.*.jpg type type # axes yes 0.8 0.02 view 60 -30 zoom 3.0 # box no 0.0 axes no 0.0 0.0 +#dump_modify 2 pad 6 + +thermo_style custom step cpu atoms ke +WARNING: New thermo_style command, previous thermo_modify settings will be lost (../output.cpp:690) +thermo_modify flush yes lost warn + +# Initial run to fill up the cone + +run 20000 +Neighbor list info ... + 2 neighbor list requests + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 1.5 + ghost atom cutoff = 1.5 + binsize = 0.75 -> bins = 40 40 94 +Memory usage per processor = 3.59417 Mbytes +Step CPU Atoms KinEng + 0 0 0 -0 + 1000 0.54582715 2000 -0 + 2000 0.93155909 2000 -0 + 3000 1.3159981 2000 -0 + 4000 1.697911 2000 -0 + 5000 2.080133 2000 -0 + 6000 2.461525 2000 -0 + 7000 2.842278 2000 -0 + 8000 3.222302 2000 -0 + 9000 3.6018171 2000 -0 + 10000 3.9843922 2000 -0 + 11000 4.363066 2000 -0 + 12000 4.743022 2000 -0 + 13000 5.121953 2000 -0 + 14000 5.5021431 2000 -0 + 15000 5.8807089 2000 -0 + 16000 6.2604752 2000 -0 + 17000 6.640244 2000 -0 + 18000 7.0199981 2000 -0 + 19000 7.40029 2000 -0 + 20000 7.7834539 2000 -0 +Loop time of 7.78348 on 1 procs for 20000 steps with 2000 atoms + +99.9% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.64588 | 0.64588 | 0.64588 | 0.0 | 8.30 +Neigh | 0.097229 | 0.097229 | 0.097229 | 0.0 | 1.25 +Comm | 0.011505 | 0.011505 | 0.011505 | 0.0 | 0.15 +Output | 0.00041127 | 0.00041127 | 0.00041127 | 0.0 | 0.01 +Modify | 6.8117 | 6.8117 | 6.8117 | 0.0 | 87.51 +Other | | 0.2168 | | | 2.79 + +Nlocal: 2000 ave 2000 max 2000 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 0 ave 0 max 0 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 1537 ave 1537 max 1537 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 1537 +Ave neighs/atom = 0.7685 +Neighbor list builds = 69 +Dangerous builds = 0 +unfix ins +run 150000 +Neighbor list info ... + 2 neighbor list requests + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 1.49993 + ghost atom cutoff = 1.49993 + binsize = 0.749963 -> bins = 41 41 94 +Memory usage per processor = 9.40639 Mbytes +Step CPU Atoms KinEng + 20000 0 2000 6443.7665 + 21000 0.37979388 2000 6572.3531 + 22000 0.76149178 2000 6723.8376 + 23000 1.1449339 2000 6853.1812 + 24000 1.529017 2000 6976.0209 + 25000 1.9145579 2000 7096.9955 + 26000 2.30124 2000 7215.5795 + 27000 2.6893978 2000 7349.2382 + 28000 3.0777299 2000 7471.8719 + 29000 3.4699018 2000 7574.7988 + 30000 3.8656738 2000 7660.2353 + 31000 4.2606828 2000 7703.5736 + 32000 4.6632309 2000 7643.5299 + 33000 5.0728998 2000 7520.14 + 34000 5.4878559 2000 7372.2247 + 35000 5.910604 2000 7192.1639 + 36000 6.340683 2000 6985.7075 + 37000 6.8159268 2000 6858.944 + 38000 7.2553098 2000 6717.0485 + 39000 7.699847 2000 6541.6874 + 40000 8.1524599 2000 6382.1661 + 41000 8.6083429 2000 6235.6681 + 42000 9.0669999 2000 6103.095 + 43000 9.5359929 2000 5951.0523 + 44000 10.012767 2000 5811.0158 + 45000 10.497891 2000 5627.7273 + 46000 10.988827 2000 5471.7262 + 47000 11.48741 2000 5299.1205 + 48000 11.990619 2000 5164.1642 + 49000 12.497663 2000 5006.5014 + 50000 13.020399 2000 4872.2336 + 51000 13.548012 2000 4694.5332 + 52000 14.082238 2000 4515.5164 + 53000 14.622731 2000 4384.7531 + 54000 15.170292 2000 4215.1354 + 55000 15.721908 2000 4063.0658 + 56000 16.285099 2000 3895.7872 + 57000 16.858606 2000 3693.0537 + 58000 17.440427 2000 3514.887 + 59000 18.03239 2000 3268.5625 + 60000 18.640969 2000 3049.7365 + 61000 19.245721 2000 2885.6786 + 62000 19.85574 2000 2652.9108 + 63000 20.47405 2000 2408.6484 + 64000 21.10165 2000 2126.9549 + 65000 21.743939 2000 1879.2829 + 66000 22.39462 2000 1645.0406 + 67000 23.059044 2000 1425.8023 + 68000 23.730976 2000 1160.2206 + 69000 24.410132 2000 961.78467 + 70000 25.096468 2000 785.64232 + 71000 25.778622 2000 626.09642 + 72000 26.474474 2000 468.40645 + 73000 27.171065 2000 358.58331 + 74000 27.860177 2000 299.43443 + 75000 28.544588 2000 246.40717 + 76000 29.226358 2000 206.30408 + 77000 29.902697 2000 176.97739 + 78000 30.577693 2000 144.25328 + 79000 31.269697 2000 115.11502 + 80000 31.977588 2000 97.780887 + 81000 32.685445 2000 82.593472 + 82000 33.397946 2000 72.226521 + 83000 34.114464 2000 62.978026 + 84000 34.831341 2000 55.350711 + 85000 35.545558 2000 51.162661 + 86000 36.266238 2000 46.100957 + 87000 36.99804 2000 41.19148 + 88000 37.743379 2000 36.31567 + 89000 38.499655 2000 32.456379 + 90000 39.270287 2000 30.16589 + 91000 40.035401 2000 27.36473 + 92000 40.799095 2000 25.488138 + 93000 41.564371 2000 23.674866 + 94000 42.335499 2000 22.219066 + 95000 43.114508 2000 20.982603 + 96000 43.897793 2000 19.840979 + 97000 44.685675 2000 19.092279 + 98000 45.483452 2000 18.20277 + 99000 46.282718 2000 17.512786 + 100000 47.085373 2000 16.921053 + 101000 47.888376 2000 16.228234 + 102000 48.698546 2000 15.958752 + 103000 49.51312 2000 15.640913 + 104000 50.330832 2000 14.016542 + 105000 51.146589 2000 13.484725 + 106000 51.96128 2000 13.369222 + 107000 52.781047 2000 12.965898 + 108000 53.604374 2000 12.268212 + 109000 54.424389 2000 11.492904 + 110000 55.253544 2000 11.110936 + 111000 56.077677 2000 10.05383 + 112000 56.904333 2000 10.159311 + 113000 57.729366 2000 10.071694 + 114000 58.559509 2000 9.820289 + 115000 59.391732 2000 9.4736012 + 116000 60.221045 2000 9.5616457 + 117000 61.052557 2000 8.6478552 + 118000 61.890195 2000 8.7425719 + 119000 62.726358 2000 8.4741204 + 120000 63.565646 2000 7.772287 + 121000 64.397804 2000 6.9466866 + 122000 65.231394 2000 6.7645153 + 123000 66.064887 2000 6.6568629 + 124000 66.901915 2000 6.7578346 + 125000 67.741833 2000 6.7845523 + 126000 68.582414 2000 6.8385357 + 127000 69.421944 2000 6.8984218 + 128000 70.262972 2000 7.031649 + 129000 71.108668 2000 6.5894805 + 130000 71.954121 2000 6.6452991 + 131000 72.795366 2000 6.7278453 + 132000 73.639866 2000 6.679577 + 133000 74.484945 2000 6.8049542 + 134000 75.326506 2000 6.9015567 + 135000 76.171268 2000 7.2052436 + 136000 77.015739 2000 7.5532841 + 137000 77.861613 2000 7.2577958 + 138000 78.706479 2000 7.5218509 + 139000 79.549466 2000 7.5221639 + 140000 80.398284 2000 7.6657717 + 141000 81.240794 2000 7.9761942 + 142000 82.087164 2000 8.2314258 + 143000 82.931215 2000 8.3019975 + 144000 83.777896 2000 8.0179905 + 145000 84.622383 2000 8.2517491 + 146000 85.469753 2000 6.9481522 + 147000 86.315756 2000 6.6131212 + 148000 87.164711 2000 6.7706881 + 149000 88.012004 2000 6.8104528 + 150000 88.861557 2000 6.7339102 + 151000 89.708494 2000 6.4777998 + 152000 90.558437 2000 6.3011889 + 153000 91.40365 2000 6.3101502 + 154000 92.249997 2000 6.5542552 + 155000 93.099774 2000 6.7687268 + 156000 93.945557 2000 6.7974687 + 157000 94.795065 2000 6.4615869 + 158000 95.645761 2000 6.5566144 + 159000 96.495711 2000 6.4371 + 160000 97.349979 2000 6.4540668 + 161000 98.19875 2000 6.6987231 + 162000 99.049934 2000 6.2464506 + 163000 99.902813 2000 4.7573102 + 164000 100.75416 2000 4.7782706 + 165000 101.60479 2000 4.9414064 + 166000 102.45183 2000 4.970526 + 167000 103.30172 2000 5.1492473 + 168000 104.15283 2000 5.3633229 + 169000 105.00583 2000 4.3464936 + 170000 105.85919 2000 3.6784016 +Loop time of 105.859 on 1 procs for 150000 steps with 2000 atoms + +99.9% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 46.786 | 46.786 | 46.786 | -nan | 44.20 +Neigh | 0.88556 | 0.88556 | 0.88556 | 0.0 | 0.84 +Comm | 0.080127 | 0.080127 | 0.080127 | 0.0 | 0.08 +Output | 0.0033967 | 0.0033967 | 0.0033967 | 0.0 | 0.00 +Modify | 56.418 | 56.418 | 56.418 | 0.0 | 53.29 +Other | | 1.687 | | | 1.59 + +Nlocal: 2000 ave 2000 max 2000 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 0 ave 0 max 0 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 15507 ave 15507 max 15507 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 15507 +Ave neighs/atom = 7.7535 +Neighbor list builds = 401 +Dangerous builds = 0 + +# remove "plug" - need to redefine cylinder region & union + +region cylreg delete +region hopreg delete +region cylreg cylinder z ${xc} ${yc} ${radconelo} ${zcyllo} ${zconelo} side in units box open 1 open 2 #Bottom & top are open +region cylreg cylinder z 25 ${yc} ${radconelo} ${zcyllo} ${zconelo} side in units box open 1 open 2 +region cylreg cylinder z 25 25 ${radconelo} ${zcyllo} ${zconelo} side in units box open 1 open 2 +region cylreg cylinder z 25 25 2 ${zcyllo} ${zconelo} side in units box open 1 open 2 +region cylreg cylinder z 25 25 2 0 ${zconelo} side in units box open 1 open 2 +region cylreg cylinder z 25 25 2 0 10 side in units box open 1 open 2 + +region hopreg union 2 cylreg conereg + +unfix hopper3 +fix hopper3 all wall/gran/region hertz/history ${kn} ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 90740.7407407408 ${gamma_n} ${gamma_t} ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 90740.7407407408 903.503751814138 ${gamma_t} ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 90740.7407407408 903.503751814138 451.751875907069 ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 90740.7407407408 903.503751814138 451.751875907069 0.5 1 region hopreg + +run 100000 +Memory usage per processor = 9.40667 Mbytes +Step CPU Atoms KinEng + 170000 0 2000 3.6784016 + 171000 0.84847808 2000 4.3936331 + 172000 1.6901879 2000 5.5750342 + 173000 2.523411 2000 6.8205762 + 174000 3.3501492 2000 8.9700613 + 175000 4.1766891 2000 11.336633 + 176000 4.9954321 2000 14.225242 + 177000 5.814229 2000 17.653262 + 178000 6.630548 2000 21.796078 + 179000 7.4493361 2000 26.660801 + 180000 8.2656369 2000 32.428193 + 181000 9.069953 2000 39.229088 + 182000 9.8759181 2000 46.242732 + 183000 10.674972 2000 54.604245 + 184000 11.47082 2000 63.96931 + 185000 12.259916 2000 74.132316 + 186000 13.046788 2000 84.690798 + 187000 13.832446 2000 95.486707 + 188000 14.612976 2000 106.68052 + 189000 15.391779 2000 118.91376 + 190000 16.160107 2000 131.90023 + 191000 16.919573 2000 146.30664 + 192000 17.677855 2000 161.10142 + 193000 18.4352 2000 174.91947 + 194000 19.188156 2000 191.47629 + 195000 19.937255 2000 208.19912 + 196000 20.687716 2000 224.80045 + 197000 21.43754 2000 243.29637 + 198000 22.18579 2000 262.88685 + 199000 22.932473 2000 282.34797 + 200000 23.680828 2000 302.78689 + 201000 24.428559 2000 323.48767 + 202000 25.167341 2000 345.99414 + 203000 25.904465 2000 368.54389 + 204000 26.635727 2000 393.49643 + 205000 27.366891 2000 417.82722 + 206000 28.094282 2000 443.67976 + 207000 28.821021 2000 470.35934 + 208000 29.545596 2000 499.01368 + 209000 30.267439 2000 528.99746 + 210000 30.993287 2000 561.03931 + 211000 31.713729 2000 594.0482 + 212000 32.42933 2000 628.20118 + 213000 33.14608 2000 662.585 + 214000 33.863882 2000 697.41408 + 215000 34.580495 2000 733.36799 + 216000 35.302571 2000 770.46796 + 217000 36.023821 2000 806.72007 + 218000 36.74189 2000 844.06965 + 219000 37.460105 2000 884.31774 + 220000 38.177705 2000 926.23771 + 221000 38.886587 2000 970.02095 + 222000 39.594003 2000 1015.3938 + 223000 40.29579 2000 1061.1281 + 224000 41.001112 2000 1107.9962 + 225000 41.706489 2000 1155.3656 + 226000 42.417622 1998 1196.6939 + 227000 43.133238 1996 1240.8434 + 228000 43.844991 1990 1260.0436 + 229000 44.545565 1986 1280.0431 + 230000 45.246651 1974 1285.222 + 231000 45.934355 1970 1311.8189 + 232000 46.624066 1960 1300.7922 + 233000 47.310339 1943 1282.113 + 234000 47.993433 1932 1261.0871 + 235000 48.66937 1918 1211.0667 + 236000 49.332954 1911 1232.6411 + 237000 49.99742 1898 1209.112 + 238000 50.664096 1888 1189.4002 + 239000 51.336205 1875 1151.415 + 240000 52.010198 1863 1108.0821 + 241000 52.680788 1856 1090.2279 + 242000 53.343069 1843 1062.9726 + 243000 53.996768 1830 1016.0933 + 244000 54.635882 1825 1023.5568 + 245000 55.271259 1817 1012.2897 + 246000 55.902793 1811 1019.8355 + 247000 56.541437 1802 996.81934 + 248000 57.182244 1793 971.29353 + 249000 57.827453 1785 947.98166 + 250000 58.473311 1771 898.58408 + 251000 59.1075 1762 851.46342 + 252000 59.73473 1754 826.46301 + 253000 60.362094 1747 808.08292 + 254000 60.989489 1737 778.86892 + 255000 61.616293 1720 702.90046 + 256000 62.243096 1709 665.14293 + 257000 62.866596 1703 628.63036 + 258000 63.48969 1702 645.42118 + 259000 64.119075 1696 617.03362 + 260000 64.752187 1692 607.96874 + 261000 65.374973 1690 619.83155 + 262000 65.991365 1688 622.09585 + 263000 66.608686 1682 612.86762 + 264000 67.220696 1681 636.53769 + 265000 67.830797 1678 638.33305 + 266000 68.439964 1675 635.97419 + 267000 69.043459 1672 634.91103 + 268000 69.643043 1669 638.50196 + 269000 70.250146 1667 646.16045 + 270000 70.86361 1664 659.62209 +Loop time of 70.8636 on 1 procs for 100000 steps with 1664 atoms + +99.9% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 33.501 | 33.501 | 33.501 | 0.0 | 47.27 +Neigh | 0.63279 | 0.63279 | 0.63279 | 0.0 | 0.89 +Comm | 0.055495 | 0.055495 | 0.055495 | 0.0 | 0.08 +Output | 0.0021648 | 0.0021648 | 0.0021648 | 0.0 | 0.00 +Modify | 35.602 | 35.602 | 35.602 | 0.0 | 50.24 +Other | | 1.07 | | | 1.51 + +Nlocal: 1664 ave 1664 max 1664 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 0 ave 0 max 0 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 11687 ave 11687 max 11687 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 11687 +Ave neighs/atom = 7.02344 +Neighbor list builds = 261 +Dangerous builds = 0 +Total wall time: 0:03:04 diff --git a/examples/granregion/log.6Oct16.granregion.funnel.g++.4 b/examples/granregion/log.6Oct16.granregion.funnel.g++.4 new file mode 100644 index 000000000..fcbd050b7 --- /dev/null +++ b/examples/granregion/log.6Oct16.granregion.funnel.g++.4 @@ -0,0 +1,608 @@ +LAMMPS (5 Oct 2016) +# pour particles into cone-shaped funnel, settle them, let them run out bottom + +variable name string funnel_pour + +thermo_modify flush yes +units si +variable PI equal 3.141592653589 +variable seed equal 14314 + +############################################### +# Geometry-related parameters +############################################### + +variable xlo equal 10 +variable xhi equal 40 +variable ylo equal 10 +variable yhi equal 40 +variable zlo equal -20 +variable zhi equal 50 + +variable xc equal 25 +variable yc equal 25 + +variable zconehi equal 50 +variable zconelo equal 10 +variable zcyllo equal 0 +variable radconelo equal 2 +variable radconehi equal 20 + +################################################ +# Particle sizes +################################################ + +variable rlo equal 0.25 +variable rhi equal 0.5 +variable dlo equal 2.0*${rlo} +variable dlo equal 2.0*0.25 +variable dhi equal 2.0*${rhi} +variable dhi equal 2.0*0.5 + +variable skin equal ${rhi} +variable skin equal 0.5 + +############################################### +# Granular contact parameters +############################################### + +variable coeffRes equal 0.1 +variable coeffFric equal 0.5 + +variable density equal 1.0 +variable EYoung equal 10^5 +variable Poisson equal 2.0/7.0 +variable GShear equal ${EYoung}/(2*(1+${Poisson})) +variable GShear equal 100000/(2*(1+${Poisson})) +variable GShear equal 100000/(2*(1+0.285714285714286)) + +variable gravity equal 1.0 + +variable reff equal 0.5*(${rhi}+${rlo}) +variable reff equal 0.5*(0.5+${rlo}) +variable reff equal 0.5*(0.5+0.25) +variable meff equal ${density}*4.0/3.0*${PI}*${reff}^3 +variable meff equal 1*4.0/3.0*${PI}*${reff}^3 +variable meff equal 1*4.0/3.0*3.141592653589*${reff}^3 +variable meff equal 1*4.0/3.0*3.141592653589*0.375^3 +variable min_mass equal ${density}*4.0/3.0*${PI}*${rlo}*${rlo}*${rlo} +variable min_mass equal 1*4.0/3.0*${PI}*${rlo}*${rlo}*${rlo} +variable min_mass equal 1*4.0/3.0*3.141592653589*${rlo}*${rlo}*${rlo} +variable min_mass equal 1*4.0/3.0*3.141592653589*0.25*${rlo}*${rlo} +variable min_mass equal 1*4.0/3.0*3.141592653589*0.25*0.25*${rlo} +variable min_mass equal 1*4.0/3.0*3.141592653589*0.25*0.25*0.25 +variable max_mass equal ${density}*4.0/3.0*${PI}*${rhi}*${rhi}*${rhi} +variable max_mass equal 1*4.0/3.0*${PI}*${rhi}*${rhi}*${rhi} +variable max_mass equal 1*4.0/3.0*3.141592653589*${rhi}*${rhi}*${rhi} +variable max_mass equal 1*4.0/3.0*3.141592653589*0.5*${rhi}*${rhi} +variable max_mass equal 1*4.0/3.0*3.141592653589*0.5*0.5*${rhi} +variable max_mass equal 1*4.0/3.0*3.141592653589*0.5*0.5*0.5 + +## Typical way to set kn, kt, etc.: +variable kn equal 4.0*${GShear}/(3*(1-${Poisson})) +variable kn equal 4.0*38888.8888888889/(3*(1-${Poisson})) +variable kn equal 4.0*38888.8888888889/(3*(1-0.285714285714286)) +variable kt equal 4.0*${GShear}/(2-${Poisson}) +variable kt equal 4.0*38888.8888888889/(2-${Poisson}) +variable kt equal 4.0*38888.8888888889/(2-0.285714285714286) + +variable a equal (-2.0*log(${coeffRes})/${PI})^2 +variable a equal (-2.0*log(0.1)/${PI})^2 +variable a equal (-2.0*log(0.1)/3.141592653589)^2 +variable gamma_n equal sqrt($a*2*${kn}/${min_mass}/(1+0.25*$a)) +variable gamma_n equal sqrt(0.405284734569556*2*${kn}/${min_mass}/(1+0.25*$a)) +variable gamma_n equal sqrt(0.405284734569556*2*72592.5925925926/${min_mass}/(1+0.25*$a)) +variable gamma_n equal sqrt(0.405284734569556*2*72592.5925925926/0.0654498469497708/(1+0.25*$a)) +variable gamma_n equal sqrt(0.405284734569556*2*72592.5925925926/0.0654498469497708/(1+0.25*0.405284734569556)) +variable gamma_t equal ${gamma_n}*0.5 +variable gamma_t equal 903.503751814138*0.5 + +variable tcol equal ${PI}/sqrt(2*${kn}/${min_mass}-${gamma_n}/4.0) +variable tcol equal 3.141592653589/sqrt(2*${kn}/${min_mass}-${gamma_n}/4.0) +variable tcol equal 3.141592653589/sqrt(2*72592.5925925926/${min_mass}-${gamma_n}/4.0) +variable tcol equal 3.141592653589/sqrt(2*72592.5925925926/0.0654498469497708-${gamma_n}/4.0) +variable tcol equal 3.141592653589/sqrt(2*72592.5925925926/0.0654498469497708-903.503751814138/4.0) + +variable dt equal ${tcol}*0.05 +variable dt equal 0.00210943016014969*0.05 +timestep ${dt} +timestep 0.000105471508007485 + +############################################### +variable dumpfreq equal 1000 +variable logfreq equal 1000 + +newton off +atom_style sphere + +boundary p p f + +region boxreg block ${xlo} ${xhi} ${ylo} ${yhi} ${zlo} ${zhi} +region boxreg block 10 ${xhi} ${ylo} ${yhi} ${zlo} ${zhi} +region boxreg block 10 40 ${ylo} ${yhi} ${zlo} ${zhi} +region boxreg block 10 40 10 ${yhi} ${zlo} ${zhi} +region boxreg block 10 40 10 40 ${zlo} ${zhi} +region boxreg block 10 40 10 40 -20 ${zhi} +region boxreg block 10 40 10 40 -20 50 +create_box 1 boxreg +Created orthogonal box = (10 10 -20) to (40 40 50) + 1 by 1 by 4 MPI processor grid + +pair_style gran/hertz/history ${kn} ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 +pair_style gran/hertz/history 72592.5925925926 ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 +pair_style gran/hertz/history 72592.5925925926 90740.7407407408 ${gamma_n} ${gamma_t} ${coeffFric} 1 +pair_style gran/hertz/history 72592.5925925926 90740.7407407408 903.503751814138 ${gamma_t} ${coeffFric} 1 +pair_style gran/hertz/history 72592.5925925926 90740.7407407408 903.503751814138 451.751875907069 ${coeffFric} 1 +pair_style gran/hertz/history 72592.5925925926 90740.7407407408 903.503751814138 451.751875907069 0.5 1 +pair_coeff * * + +neighbor ${skin} bin +neighbor 0.5 bin +thermo ${logfreq} +thermo 1000 + +comm_style brick +comm_modify mode multi group all vel yes +balance 1.1 shift xyz 20 1.1 +Neighbor list info ... + 2 neighbor list requests + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 0 + ghost atom cutoff = 0 + binsize = 30 -> bins = 1 1 3 +fix bal all balance 10000 1.1 shift xyz 20 1.01 + +####################### Options specific to pouring ######################### + +# insertion region for fix/pour + +region insreg cylinder z ${xc} ${yc} 10 30 50 side in units box +region insreg cylinder z 25 ${yc} 10 30 50 side in units box +region insreg cylinder z 25 25 10 30 50 side in units box + +# define cone and cylinder regions - see lammps doc on region command +# note new open options + +region cylreg cylinder z ${xc} ${yc} ${radconelo} ${zcyllo} ${zconelo} side in units box open 2 #Top is open +region cylreg cylinder z 25 ${yc} ${radconelo} ${zcyllo} ${zconelo} side in units box open 2 +region cylreg cylinder z 25 25 ${radconelo} ${zcyllo} ${zconelo} side in units box open 2 +region cylreg cylinder z 25 25 2 ${zcyllo} ${zconelo} side in units box open 2 +region cylreg cylinder z 25 25 2 0 ${zconelo} side in units box open 2 +region cylreg cylinder z 25 25 2 0 10 side in units box open 2 + +region conereg cone z ${xc} ${yc} ${radconelo} ${radconehi} ${zconelo} ${zconehi} side in units box open 1 open 2 #Bottom and top are open +region conereg cone z 25 ${yc} ${radconelo} ${radconehi} ${zconelo} ${zconehi} side in units box open 1 open 2 +region conereg cone z 25 25 ${radconelo} ${radconehi} ${zconelo} ${zconehi} side in units box open 1 open 2 +region conereg cone z 25 25 2 ${radconehi} ${zconelo} ${zconehi} side in units box open 1 open 2 +region conereg cone z 25 25 2 20 ${zconelo} ${zconehi} side in units box open 1 open 2 +region conereg cone z 25 25 2 20 10 ${zconehi} side in units box open 1 open 2 +region conereg cone z 25 25 2 20 10 50 side in units box open 1 open 2 + +region hopreg union 2 conereg cylreg + +fix grav all gravity ${gravity} vector 0 0 -1 +fix grav all gravity 1 vector 0 0 -1 +fix 1 all nve/sphere + + +fix hopper3 all wall/gran/region hertz/history ${kn} ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 90740.7407407408 ${gamma_n} ${gamma_t} ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 90740.7407407408 903.503751814138 ${gamma_t} ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 90740.7407407408 903.503751814138 451.751875907069 ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 90740.7407407408 903.503751814138 451.751875907069 0.5 1 region hopreg + +fix ins all pour 2000 1 42424 region insreg diam range ${dlo} ${dhi} dens ${density} ${density} +fix ins all pour 2000 1 42424 region insreg diam range 0.5 ${dhi} dens ${density} ${density} +fix ins all pour 2000 1 42424 region insreg diam range 0.5 1 dens ${density} ${density} +fix ins all pour 2000 1 42424 region insreg diam range 0.5 1 dens 1 ${density} +fix ins all pour 2000 1 42424 region insreg diam range 0.5 1 dens 1 1 +Particle insertion: 3000 every 59965 steps, 2000 by step 1 + +#dump 1 all custom ${dumpfreq} ${name}.dump # id type mass diameter x y z + +#dump 2 all image 4000 image.*.jpg type type # axes yes 0.8 0.02 view 60 -30 zoom 3.0 # box no 0.0 axes no 0.0 0.0 +#dump_modify 2 pad 6 + +thermo_style custom step cpu atoms ke +WARNING: New thermo_style command, previous thermo_modify settings will be lost (../output.cpp:690) +thermo_modify flush yes lost warn + +# Initial run to fill up the cone + +run 20000 +Neighbor list info ... + 2 neighbor list requests + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 1.5 + ghost atom cutoff = 1.5 + binsize = 0.75 -> bins = 40 40 94 +Memory usage per processor = 2.99539 Mbytes +Step CPU Atoms KinEng + 0 0 0 -0 + 1000 0.53632808 2000 -0 + 2000 0.90599012 2000 -0 + 3000 1.2640941 2000 -0 + 4000 1.6225331 2000 -0 + 5000 1.9735272 2000 -0 + 6000 2.3156731 2000 -0 + 7000 2.6499262 2000 -0 + 8000 2.9751072 2000 -0 + 9000 3.2918322 2000 -0 + 10000 3.597712 2000 -0 + 11000 3.7157061 2000 -0 + 12000 3.833451 2000 -0 + 13000 3.9541111 2000 -0 + 14000 4.081727 2000 -0 + 15000 4.2142782 2000 -0 + 16000 4.3530872 2000 -0 + 17000 4.4987361 2000 -0 + 18000 4.6507492 2000 -0 + 19000 4.807373 2000 -0 + 20000 4.9710512 2000 -0 +Loop time of 4.97109 on 4 procs for 20000 steps with 2000 atoms + +98.5% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.067799 | 0.17326 | 0.37341 | 28.4 | 3.49 +Neigh | 0.013881 | 0.025808 | 0.045841 | 7.5 | 0.52 +Comm | 0.078163 | 0.1808 | 0.2915 | 21.0 | 3.64 +Output | 0.0011413 | 0.0027029 | 0.0036721 | 1.8 | 0.05 +Modify | 1.0146 | 1.8605 | 3.562 | 73.8 | 37.43 +Other | | 2.728 | | | 54.88 + +Nlocal: 500 ave 505 max 493 min +Histogram: 1 0 0 0 0 1 0 1 0 1 +Nghost: 159.25 ave 254 max 71 min +Histogram: 1 0 0 1 0 1 0 0 0 1 +Neighs: 397.5 ave 616 max 214 min +Histogram: 1 0 1 0 0 0 1 0 0 1 + +Total # of neighbors = 1590 +Ave neighs/atom = 0.795 +Neighbor list builds = 69 +Dangerous builds = 0 +unfix ins +run 150000 +Neighbor list info ... + 2 neighbor list requests + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 1.49993 + ghost atom cutoff = 1.49993 + binsize = 0.749963 -> bins = 41 41 94 +Memory usage per processor = 9.39737 Mbytes +Step CPU Atoms KinEng + 20000 0 2000 6443.7665 + 21000 0.11240888 2000 6572.3531 + 22000 0.23014092 2000 6723.8376 + 23000 0.35371184 2000 6853.1812 + 24000 0.4838469 2000 6976.0209 + 25000 0.62193394 2000 7096.9955 + 26000 0.76781893 2000 7215.5795 + 27000 0.92212081 2000 7349.2382 + 28000 1.0841098 2000 7471.8719 + 29000 1.2593179 2000 7574.7988 + 30000 1.4459748 2000 7660.2353 + 31000 1.5759299 2000 7703.5736 + 32000 1.7189329 2000 7643.5299 + 33000 1.876133 2000 7520.14 + 34000 2.0453629 2000 7372.2247 + 35000 2.2281299 2000 7192.1638 + 36000 2.4208269 2000 6985.7056 + 37000 2.6258228 2000 6858.9422 + 38000 2.839473 2000 6717.0655 + 39000 3.065336 2000 6541.5809 + 40000 3.3090389 2000 6381.8513 + 41000 3.4969938 2000 6236.4297 + 42000 3.6888108 2000 6104.2528 + 43000 3.8874888 2000 5951.0314 + 44000 4.0956569 2000 5819.0972 + 45000 4.312974 2000 5620.6457 + 46000 4.5343778 2000 5479.332 + 47000 4.757262 2000 5295.328 + 48000 4.9850328 2000 5179.9559 + 49000 5.2210319 2000 5022.5562 + 50000 5.4699879 2000 4899.1332 + 51000 5.6774018 2000 4699.4456 + 52000 5.8900218 2000 4522.5719 + 53000 6.110677 2000 4402.8664 + 54000 6.3361218 2000 4256.1664 + 55000 6.5778289 2000 4093.6265 + 56000 6.8319149 2000 3933.0179 + 57000 7.0925779 2000 3738.4628 + 58000 7.3578169 2000 3535.7866 + 59000 7.6344049 2000 3298.4079 + 60000 7.9258108 2000 3058.9356 + 61000 8.1758959 2000 2888.0074 + 62000 8.4278228 2000 2652.4613 + 63000 8.6815088 2000 2435.0991 + 64000 8.9371588 2000 2147.9441 + 65000 9.208025 2000 1898.0657 + 66000 9.4795358 2000 1650.5794 + 67000 9.7519388 2000 1425.7284 + 68000 10.025867 2000 1193.3786 + 69000 10.313816 2000 940.55767 + 70000 10.610488 2000 761.5312 + 71000 10.879718 2000 599.1989 + 72000 11.154029 2000 453.25929 + 73000 11.424376 2000 345.73222 + 74000 11.697359 2000 273.72167 + 75000 11.966099 2000 222.44251 + 76000 12.230213 2000 190.79993 + 77000 12.481982 2000 157.71153 + 78000 12.73433 2000 131.99208 + 79000 12.986017 2000 111.10589 + 80000 13.243904 2000 96.736337 + 81000 13.500538 2000 81.24169 + 82000 13.765755 2000 66.640863 + 83000 14.032985 2000 53.07725 + 84000 14.308284 2000 45.942738 + 85000 14.586721 2000 38.811918 + 86000 14.861759 2000 34.59113 + 87000 15.135665 2000 31.04487 + 88000 15.417487 2000 27.659144 + 89000 15.698281 2000 24.596119 + 90000 15.97969 2000 22.004865 + 91000 16.266118 2000 20.541665 + 92000 16.557007 2000 18.938077 + 93000 16.846745 2000 17.293956 + 94000 17.133408 2000 16.443596 + 95000 17.42023 2000 15.518083 + 96000 17.709025 2000 14.264343 + 97000 18.001337 2000 13.410217 + 98000 18.292414 2000 13.036621 + 99000 18.583887 2000 12.523214 + 100000 18.880312 2000 12.371509 + 101000 19.176964 2000 11.828077 + 102000 19.474371 2000 11.510333 + 103000 19.770957 2000 11.289304 + 104000 20.070744 2000 10.370661 + 105000 20.372617 2000 10.217921 + 106000 20.673949 2000 9.3275222 + 107000 20.9765 2000 8.9156372 + 108000 21.276062 2000 8.5850821 + 109000 21.585305 2000 8.5326934 + 110000 21.89079 2000 8.0579504 + 111000 22.194207 2000 8.1084595 + 112000 22.501593 2000 7.9190174 + 113000 22.81251 2000 8.0127499 + 114000 23.118514 2000 8.1791911 + 115000 23.432862 2000 8.3333032 + 116000 23.735549 2000 8.4833817 + 117000 24.038329 2000 8.315498 + 118000 24.343247 2000 7.9460007 + 119000 24.643288 2000 7.5922134 + 120000 24.94731 2000 7.4089143 + 121000 25.253605 2000 7.5790659 + 122000 25.56672 2000 7.3778204 + 123000 25.870958 2000 7.1384456 + 124000 26.180729 2000 6.9151887 + 125000 26.493089 2000 6.4671685 + 126000 26.806734 2000 5.6773128 + 127000 27.10969 2000 5.5603057 + 128000 27.410973 2000 5.6376136 + 129000 27.712398 2000 5.5578044 + 130000 28.015943 2000 5.4632646 + 131000 28.319002 2000 4.9669466 + 132000 28.620558 2000 5.0191026 + 133000 28.923233 2000 4.7146653 + 134000 29.235178 2000 4.4835803 + 135000 29.542816 2000 4.5469703 + 136000 29.8518 2000 4.3349926 + 137000 30.159096 2000 4.423031 + 138000 30.464283 2000 4.3680646 + 139000 30.769279 2000 4.2461787 + 140000 31.074457 2000 4.4140001 + 141000 31.380334 2000 4.3991236 + 142000 31.683855 2000 4.572989 + 143000 31.987308 2000 4.7601702 + 144000 32.28998 2000 4.7790587 + 145000 32.594971 2000 4.8127728 + 146000 32.89855 2000 4.8750003 + 147000 33.205142 2000 4.9830109 + 148000 33.509096 2000 4.9960037 + 149000 33.812951 2000 5.2151503 + 150000 34.117585 2000 5.2745187 + 151000 34.420995 2000 4.8959892 + 152000 34.725788 2000 4.7600627 + 153000 35.032001 2000 4.6944719 + 154000 35.337093 2000 4.7647384 + 155000 35.645299 2000 4.312228 + 156000 35.953225 2000 3.8513036 + 157000 36.258107 2000 3.8798947 + 158000 36.570122 2000 3.7116749 + 159000 36.880424 2000 3.7246469 + 160000 37.187331 2000 3.8165318 + 161000 37.491939 2000 3.8954595 + 162000 37.806365 2000 4.0109691 + 163000 38.122006 2000 3.3864369 + 164000 38.437246 2000 3.4533589 + 165000 38.753073 2000 3.4967205 + 166000 39.068713 2000 3.5758702 + 167000 39.376388 2000 2.8913997 + 168000 39.685628 2000 2.507523 + 169000 39.99294 2000 2.4910068 + 170000 40.302393 2000 2.4992886 +Loop time of 40.3024 on 4 procs for 150000 steps with 2000 atoms + +99.2% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 7.9352 | 13.451 | 15.947 | 88.7 | 33.37 +Neigh | 0.15394 | 0.23292 | 0.28243 | 10.0 | 0.58 +Comm | 2.1471 | 3.534 | 4.4671 | 47.3 | 8.77 +Output | 0.0070386 | 0.011774 | 0.021483 | 5.4 | 0.03 +Modify | 10.816 | 14.404 | 16.047 | 55.2 | 35.74 +Other | | 8.669 | | | 21.51 + +Nlocal: 500 ave 542 max 430 min +Histogram: 1 0 0 0 0 0 1 0 1 1 +Nghost: 449.5 ave 679 max 208 min +Histogram: 1 0 0 0 1 0 1 0 0 1 +Neighs: 4506.75 ave 5611 max 3508 min +Histogram: 1 0 1 0 0 0 1 0 0 1 + +Total # of neighbors = 18027 +Ave neighs/atom = 9.0135 +Neighbor list builds = 386 +Dangerous builds = 0 + +# remove "plug" - need to redefine cylinder region & union + +region cylreg delete +region hopreg delete +region cylreg cylinder z ${xc} ${yc} ${radconelo} ${zcyllo} ${zconelo} side in units box open 1 open 2 #Bottom & top are open +region cylreg cylinder z 25 ${yc} ${radconelo} ${zcyllo} ${zconelo} side in units box open 1 open 2 +region cylreg cylinder z 25 25 ${radconelo} ${zcyllo} ${zconelo} side in units box open 1 open 2 +region cylreg cylinder z 25 25 2 ${zcyllo} ${zconelo} side in units box open 1 open 2 +region cylreg cylinder z 25 25 2 0 ${zconelo} side in units box open 1 open 2 +region cylreg cylinder z 25 25 2 0 10 side in units box open 1 open 2 + +region hopreg union 2 cylreg conereg + +unfix hopper3 +fix hopper3 all wall/gran/region hertz/history ${kn} ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 90740.7407407408 ${gamma_n} ${gamma_t} ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 90740.7407407408 903.503751814138 ${gamma_t} ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 90740.7407407408 903.503751814138 451.751875907069 ${coeffFric} 1 region hopreg +fix hopper3 all wall/gran/region hertz/history 72592.5925925926 90740.7407407408 903.503751814138 451.751875907069 0.5 1 region hopreg + +run 100000 +Memory usage per processor = 9.41929 Mbytes +Step CPU Atoms KinEng + 170000 0 2000 2.4992886 + 171000 0.30864286 2000 3.6052039 + 172000 0.62273479 2000 4.8584577 + 173000 0.94411087 2000 6.5620833 + 174000 1.2588799 2000 8.8636423 + 175000 1.574302 2000 11.743197 + 176000 1.888201 2000 15.60405 + 177000 2.1948938 2000 20.29426 + 178000 2.508261 2000 25.069266 + 179000 2.8257489 2000 31.340924 + 180000 3.1444538 2000 38.454779 + 181000 3.4541628 2000 46.488676 + 182000 3.7632799 2000 55.279578 + 183000 4.0711808 2000 65.192327 + 184000 4.386853 2000 75.466011 + 185000 4.7000408 2000 86.06934 + 186000 5.00436 2000 97.157035 + 187000 5.3041189 2000 108.92242 + 188000 5.601872 2000 120.88599 + 189000 5.9027078 2000 134.09884 + 190000 6.2037618 2000 148.60143 + 191000 6.4879329 2000 163.96898 + 192000 6.7703898 2000 180.32931 + 193000 7.0603459 2000 198.83575 + 194000 7.3395619 2000 217.46631 + 195000 7.6245389 2000 235.34916 + 196000 7.911685 2000 253.61893 + 197000 8.1976559 2000 271.3908 + 198000 8.483418 2000 289.60064 + 199000 8.7664149 2000 309.44306 + 200000 9.0593698 2000 331.9367 + 201000 9.3373818 2000 354.86646 + 202000 9.612149 2000 380.56766 + 203000 9.8876739 2000 406.97399 + 204000 10.152671 2000 435.69917 + 205000 10.415859 2000 465.1954 + 206000 10.67967 2000 494.6045 + 207000 10.941435 2000 522.71704 + 208000 11.205367 2000 550.56072 + 209000 11.471415 2000 580.10547 + 210000 11.738137 2000 610.36222 + 211000 12.006432 2000 641.99128 + 212000 12.270102 2000 676.0736 + 213000 12.531937 2000 711.70118 + 214000 12.797442 2000 747.84561 + 215000 13.062646 2000 785.59575 + 216000 13.33019 2000 826.36549 + 217000 13.598467 2000 868.35085 + 218000 13.863022 2000 911.07041 + 219000 14.127777 2000 953.70251 + 220000 14.391496 2000 997.5717 + 221000 14.655347 2000 1043.5565 + 222000 14.923357 2000 1090.7944 + 223000 15.193349 2000 1140.1324 + 224000 15.462326 2000 1190.6956 + 225000 15.729748 1999 1238.1536 + 226000 15.996867 1998 1286.8076 + 227000 16.261762 1995 1326.9895 + 228000 16.527382 1989 1349.5997 + 229000 16.788356 1984 1370.593 + 230000 17.05426 1968 1344.3763 + 231000 17.320126 1962 1363.7958 + 232000 17.58387 1949 1340.1482 + 233000 17.850221 1940 1348.409 + 234000 18.116595 1929 1335.9703 + 235000 18.383276 1918 1328.201 + 236000 18.650066 1905 1309.6469 + 237000 18.916963 1896 1292.9758 + 238000 19.185209 1884 1266.3598 + 239000 19.453402 1872 1221.0069 + 240000 19.722178 1855 1166.1488 + 241000 19.98987 1842 1126.9482 + 242000 20.257783 1828 1107.128 + 243000 20.523743 1815 1060.6573 + 244000 20.793404 1805 1026.0259 + 245000 21.061462 1797 1009.4924 + 246000 21.325574 1790 995.26136 + 247000 21.587046 1782 976.04886 + 248000 21.840234 1778 989.11589 + 249000 22.09455 1762 903.62508 + 250000 22.356228 1748 852.03257 + 251000 22.602243 1738 807.41049 + 252000 22.852106 1722 738.82529 + 253000 23.097209 1712 706.05657 + 254000 23.341263 1696 626.53135 + 255000 23.58614 1692 613.89548 + 256000 23.83122 1686 598.9367 + 257000 24.076937 1683 589.27487 + 258000 24.321166 1681 591.42793 + 259000 24.566143 1678 595.25383 + 260000 24.820743 1677 617.50379 + 261000 25.057835 1675 623.39319 + 262000 25.294068 1673 627.08829 + 263000 25.526724 1669 623.52963 + 264000 25.766729 1667 626.44957 + 265000 26.005453 1664 631.58936 + 266000 26.244549 1660 605.22452 + 267000 26.478879 1657 611.76935 + 268000 26.71252 1655 611.73538 + 269000 26.951368 1652 624.58227 + 270000 27.186447 1648 625.97446 +Loop time of 27.1865 on 4 procs for 100000 steps with 1648 atoms + +99.2% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 4.6257 | 9.631 | 13.049 | 100.0 | 35.43 +Neigh | 0.1522 | 0.17549 | 0.19588 | 4.3 | 0.65 +Comm | 1.5797 | 2.7289 | 3.602 | 48.7 | 10.04 +Output | 0.0014181 | 0.007208 | 0.016675 | 6.8 | 0.03 +Modify | 7.7129 | 9.0949 | 10.256 | 31.9 | 33.45 +Other | | 5.549 | | | 20.41 + +Nlocal: 412 ave 436 max 388 min +Histogram: 1 1 0 0 0 0 0 0 1 1 +Nghost: 391 ave 629 max 158 min +Histogram: 1 0 0 1 0 1 0 0 0 1 +Neighs: 3406 ave 4479 max 2040 min +Histogram: 1 0 0 0 1 0 0 1 0 1 + +Total # of neighbors = 13624 +Ave neighs/atom = 8.26699 +Neighbor list builds = 260 +Dangerous builds = 0 +Total wall time: 0:01:12 diff --git a/examples/granregion/log.6Oct16.granregion.mixer.g++.1 b/examples/granregion/log.6Oct16.granregion.mixer.g++.1 new file mode 100644 index 000000000..3cfa3eb0f --- /dev/null +++ b/examples/granregion/log.6Oct16.granregion.mixer.g++.1 @@ -0,0 +1,609 @@ +LAMMPS (5 Oct 2016) +variable name string mixer + +thermo_modify flush yes +variable seed equal 14314 + +############################################### +# Particle parameters +################################################ + +variable rlo equal 0.3 +variable rhi equal 0.6 +variable dlo equal 2.0*${rlo} +variable dlo equal 2.0*0.3 +variable dhi equal 2.0*${rhi} +variable dhi equal 2.0*0.6 +variable skin equal ${rhi} +variable skin equal 0.6 + +variable coeffRes equal 0.1 +variable coeffFric equal 0.5 + +variable kn equal 10^5 +variable kt equal 0.2*${kn} +variable kt equal 0.2*100000 + +variable gravity equal 1.0 +variable density equal 1.0 + +variable min_mass equal ${density}*4.0/3.0*PI*${rlo}*${rlo}*${rlo} +variable min_mass equal 1*4.0/3.0*PI*${rlo}*${rlo}*${rlo} +variable min_mass equal 1*4.0/3.0*PI*0.3*${rlo}*${rlo} +variable min_mass equal 1*4.0/3.0*PI*0.3*0.3*${rlo} +variable min_mass equal 1*4.0/3.0*PI*0.3*0.3*0.3 +variable a equal (-2.0*log(${coeffRes})/PI)^2 +variable a equal (-2.0*log(0.1)/PI)^2 +variable gamma_n equal sqrt($a*2*${kn}/${min_mass}/(1+0.25*$a)) +variable gamma_n equal sqrt(0.405284734569351*2*${kn}/${min_mass}/(1+0.25*$a)) +variable gamma_n equal sqrt(0.405284734569351*2*100000/${min_mass}/(1+0.25*$a)) +variable gamma_n equal sqrt(0.405284734569351*2*100000/0.113097335529233/(1+0.25*$a)) +variable gamma_n equal sqrt(0.405284734569351*2*100000/0.113097335529233/(1+0.25*0.405284734569351)) +variable gamma_t equal ${gamma_n}*0.5 +variable gamma_t equal 806.699778405191*0.5 + +variable tcol equal PI/sqrt(2*${kn}/${min_mass}-${gamma_n}/4.0) +variable tcol equal PI/sqrt(2*100000/${min_mass}-${gamma_n}/4.0) +variable tcol equal PI/sqrt(2*100000/0.113097335529233-${gamma_n}/4.0) +variable tcol equal PI/sqrt(2*100000/0.113097335529233-806.699778405191/4.0) + +variable dt equal ${tcol}*0.02 +variable dt equal 0.00236257621510454*0.02 +timestep ${dt} +timestep 4.72515243020908e-05 + +############################################### + +variable dumpfreq equal 1000 +variable logfreq equal 1000 + +newton on +atom_style sphere + +boundary p p f + +region boxreg block 0 20 0 20 0 20 +create_box 1 boxreg +Created orthogonal box = (0 0 0) to (20 20 20) + 1 by 1 by 1 MPI processor grid + +pair_style gran/hertz/history ${kn} ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 +pair_style gran/hertz/history 100000 ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 +pair_style gran/hertz/history 100000 20000 ${gamma_n} ${gamma_t} ${coeffFric} 1 +pair_style gran/hertz/history 100000 20000 806.699778405191 ${gamma_t} ${coeffFric} 1 +pair_style gran/hertz/history 100000 20000 806.699778405191 403.349889202595 ${coeffFric} 1 +pair_style gran/hertz/history 100000 20000 806.699778405191 403.349889202595 0.5 1 +pair_coeff * * + +neighbor ${skin} bin +neighbor 0.6 bin +thermo ${logfreq} +thermo 1000 + +comm_style brick +comm_modify mode multi group all vel yes +balance 1.1 shift xyz 20 1.1 +Neighbor list info ... + 2 neighbor list requests + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 0 + ghost atom cutoff = 0 + binsize = 20 -> bins = 1 1 1 +fix bal all balance 10000 1.1 shift xyz 20 1.01 + +####################### Options specific to pouring ######################### + +region insreg cylinder z 10 10 8 10 18 side in units box +region cylreg cylinder z 10 10 10 0 20 side in units box + +variable theta equal (step/400000)*2*PI + +region b1 block 2 18 9 11 0 4 side out rotate v_theta 10 10 0 0 0 1 units box +region b2 block 9 11 2 18 0 3.99999 side out rotate v_theta 10 10 0 0 0 1 units box + +region mixer intersect 3 cylreg b1 b2 side in + +fix grav all gravity ${gravity} vector 0 0 -1 +fix grav all gravity 1 vector 0 0 -1 +fix 1 all nve/sphere + +fix mixwall all wall/gran/region hertz/history ${kn} ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 region mixer +fix mixwall all wall/gran/region hertz/history 100000 ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 region mixer +fix mixwall all wall/gran/region hertz/history 100000 20000 ${gamma_n} ${gamma_t} ${coeffFric} 1 region mixer +fix mixwall all wall/gran/region hertz/history 100000 20000 806.699778405191 ${gamma_t} ${coeffFric} 1 region mixer +fix mixwall all wall/gran/region hertz/history 100000 20000 806.699778405191 403.349889202595 ${coeffFric} 1 region mixer +fix mixwall all wall/gran/region hertz/history 100000 20000 806.699778405191 403.349889202595 0.5 1 region mixer + +fix ins all pour 1000 1 42424 region insreg diam range ${dlo} ${dhi} dens ${density} ${density} +fix ins all pour 1000 1 42424 region insreg diam range 0.6 ${dhi} dens ${density} ${density} +fix ins all pour 1000 1 42424 region insreg diam range 0.6 1.2 dens ${density} ${density} +fix ins all pour 1000 1 42424 region insreg diam range 0.6 1.2 dens 1 ${density} +fix ins all pour 1000 1 42424 region insreg diam range 0.6 1.2 dens 1 1 +Particle insertion: 444 every 84653 steps, 1000 by step 169307 + +#dump 1 all custom ${dumpfreq} ${name}_pour.dump # id type mass diameter x y z + +#dump 2 all image 4000 image.*.jpg type type # axes yes 0.8 0.02 view 60 -30 zoom 1.5 # box no 0.0 axes no 0.0 0.0 +#dump_modify 2 pad 6 + +thermo_style custom step cpu atoms ke v_theta +WARNING: New thermo_style command, previous thermo_modify settings will be lost (../output.cpp:690) +thermo_modify flush yes lost warn + +run 200000 +Neighbor list info ... + 2 neighbor list requests + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 1.8 + ghost atom cutoff = 1.8 + binsize = 0.9 -> bins = 23 23 23 +Memory usage per processor = 2.80779 Mbytes +Step CPU Atoms KinEng v_theta + 0 0 0 -0 0 + 1000 0.16771817 444 -0 0.015707963 + 2000 0.33019304 444 -0 0.031415927 + 3000 0.4894321 444 -0 0.04712389 + 4000 0.64879322 444 -0 0.062831853 + 5000 0.80816507 444 -0 0.078539816 + 6000 0.96711302 444 -0 0.09424778 + 7000 1.1265812 444 -0 0.10995574 + 8000 1.286129 444 -0 0.12566371 + 9000 1.445487 444 -0 0.14137167 + 10000 1.6056392 444 -0 0.15707963 + 11000 1.7650061 444 -0 0.1727876 + 12000 1.9249642 444 -0 0.18849556 + 13000 2.0851831 444 -0 0.20420352 + 14000 2.244523 444 -0 0.21991149 + 15000 2.4043641 444 -0 0.23561945 + 16000 2.5638251 444 -0 0.25132741 + 17000 2.7155962 444 -0 0.26703538 + 18000 2.866904 444 -0 0.28274334 + 19000 3.0188181 444 -0 0.2984513 + 20000 3.17047 444 -0 0.31415927 + 21000 3.3214712 444 -0 0.32986723 + 22000 3.472692 444 -0 0.34557519 + 23000 3.6240032 444 -0 0.36128316 + 24000 3.7753551 444 -0 0.37699112 + 25000 3.926239 444 -0 0.39269908 + 26000 4.0782132 444 -0 0.40840704 + 27000 4.2301712 444 -0 0.42411501 + 28000 4.382267 444 -0 0.43982297 + 29000 4.5339992 444 -0 0.45553093 + 30000 4.6860211 444 -0 0.4712389 + 31000 4.8376751 444 -0 0.48694686 + 32000 4.989748 444 -0 0.50265482 + 33000 5.1418142 444 -0 0.51836279 + 34000 5.294476 444 -0 0.53407075 + 35000 5.4472861 444 -0 0.54977871 + 36000 5.5999811 444 -0 0.56548668 + 37000 5.7526181 444 -0 0.58119464 + 38000 5.9061031 444 -0 0.5969026 + 39000 6.0593271 444 -0 0.61261057 + 40000 6.2123802 444 -0 0.62831853 + 41000 6.3652351 444 -0 0.64402649 + 42000 6.5186551 444 -0 0.65973446 + 43000 6.672132 444 -0 0.67544242 + 44000 6.8245611 444 -0 0.69115038 + 45000 6.9778051 444 -0 0.70685835 + 46000 7.131258 444 -0 0.72256631 + 47000 7.2841291 444 -0 0.73827427 + 48000 7.4379101 444 -0 0.75398224 + 49000 7.5915 444 -0 0.7696902 + 50000 7.7461231 444 -0 0.78539816 + 51000 7.9047191 444 -0 0.80110613 + 52000 8.0634432 444 -0 0.81681409 + 53000 8.2226322 444 -0 0.83252205 + 54000 8.3817451 444 -0 0.84823002 + 55000 8.5419021 444 -0 0.86393798 + 56000 8.701194 444 -0 0.87964594 + 57000 8.8613491 444 -0 0.89535391 + 58000 9.0211501 444 -0 0.91106187 + 59000 9.180917 444 -0 0.92676983 + 60000 9.341964 444 -0 0.9424778 + 61000 9.5026722 444 -0 0.95818576 + 62000 9.6630561 444 -0 0.97389372 + 63000 9.8236201 444 -0 0.98960169 + 64000 9.9854801 444 -0 1.0053096 + 65000 10.148318 444 -0 1.0210176 + 66000 10.311267 444 -0 1.0367256 + 67000 10.476498 444 -0 1.0524335 + 68000 10.640768 444 -0 1.0681415 + 69000 10.804709 444 -0 1.0838495 + 70000 10.969271 444 -0 1.0995574 + 71000 11.133451 444 -0 1.1152654 + 72000 11.299253 444 -0 1.1309734 + 73000 11.463999 444 -0 1.1466813 + 74000 11.62903 444 -0 1.1623893 + 75000 11.795109 444 -0 1.1780972 + 76000 11.962154 444 -0 1.1938052 + 77000 12.1292 444 -0 1.2095132 + 78000 12.298106 444 -0 1.2252211 + 79000 12.46744 444 -0 1.2409291 + 80000 12.637916 444 -0 1.2566371 + 81000 12.808494 444 -0 1.272345 + 82000 12.97813 444 -0 1.288053 + 83000 13.149135 444 -0 1.303761 + 84000 13.32082 444 -0 1.3194689 + 85000 13.56205 888 -0 1.3351769 + 86000 13.908699 888 -0 1.3508848 + 87000 14.254615 888 -0 1.3665928 + 88000 14.600851 888 -0 1.3823008 + 89000 14.946295 888 -0 1.3980087 + 90000 15.291315 888 -0 1.4137167 + 91000 15.637396 888 -0 1.4294247 + 92000 15.981426 888 -0 1.4451326 + 93000 16.327519 888 -0 1.4608406 + 94000 16.675434 888 -0 1.4765485 + 95000 17.023515 888 -0 1.4922565 + 96000 17.372152 888 -0 1.5079645 + 97000 17.719346 888 -0 1.5236724 + 98000 18.067159 888 -0 1.5393804 + 99000 18.414599 888 -0 1.5550884 + 100000 18.764775 888 -0 1.5707963 + 101000 19.114239 888 -0 1.5865043 + 102000 19.464285 888 -0 1.6022123 + 103000 19.813956 888 -0 1.6179202 + 104000 20.163276 888 -0 1.6336282 + 105000 20.553808 888 -0 1.6493361 + 106000 20.904093 888 -0 1.6650441 + 107000 21.25918 888 -0 1.6807521 + 108000 21.615056 888 -0 1.69646 + 109000 21.971067 888 -0 1.712168 + 110000 22.326407 888 -0 1.727876 + 111000 22.68062 888 -0 1.7435839 + 112000 23.03653 888 -0 1.7592919 + 113000 23.39161 888 -0 1.7749998 + 114000 23.751273 888 -0 1.7907078 + 115000 24.106946 888 -0 1.8064158 + 116000 24.461182 888 -0 1.8221237 + 117000 24.797533 888 -0 1.8378317 + 118000 25.133924 888 -0 1.8535397 + 119000 25.472617 888 -0 1.8692476 + 120000 25.810786 888 -0 1.8849556 + 121000 26.147399 888 -0 1.9006636 + 122000 26.485868 888 -0 1.9163715 + 123000 26.82395 888 -0 1.9320795 + 124000 27.162345 888 -0 1.9477874 + 125000 27.501503 888 -0 1.9634954 + 126000 27.843318 888 -0 1.9792034 + 127000 28.183379 888 -0 1.9949113 + 128000 28.525406 888 -0 2.0106193 + 129000 28.869601 888 -0 2.0263273 + 130000 29.216232 888 -0 2.0420352 + 131000 29.562432 888 -0 2.0577432 + 132000 29.95624 888 -0 2.0734512 + 133000 30.308919 888 -0 2.0891591 + 134000 30.662184 888 -0 2.1048671 + 135000 31.015509 888 -0 2.120575 + 136000 31.366132 888 -0 2.136283 + 137000 31.71887 888 -0 2.151991 + 138000 32.0723 888 -0 2.1676989 + 139000 32.428657 888 -0 2.1834069 + 140000 32.781484 888 -0 2.1991149 + 141000 33.133593 888 -0 2.2148228 + 142000 33.487376 888 -0 2.2305308 + 143000 33.838656 888 -0 2.2462387 + 144000 34.188723 888 -0 2.2619467 + 145000 34.540083 888 -0 2.2776547 + 146000 34.895624 888 -0 2.2933626 + 147000 35.25153 888 -0 2.3090706 + 148000 35.607482 888 -0 2.3247786 + 149000 35.9642 888 -0 2.3404865 + 150000 36.321759 888 -0 2.3561945 + 151000 36.667172 888 -0 2.3719025 + 152000 37.013822 888 -0 2.3876104 + 153000 37.362735 888 -0 2.4033184 + 154000 37.712576 888 -0 2.4190263 + 155000 38.063528 888 -0 2.4347343 + 156000 38.414666 888 -0 2.4504423 + 157000 38.766119 888 -0 2.4661502 + 158000 39.115828 888 -0 2.4818582 + 159000 39.470874 888 -0 2.4975662 + 160000 39.827871 888 -0 2.5132741 + 161000 40.184885 888 -0 2.5289821 + 162000 40.543838 888 -0 2.54469 + 163000 40.901814 888 -0 2.560398 + 164000 41.258631 888 -0 2.576106 + 165000 41.619086 888 -0 2.5918139 + 166000 41.977332 888 -0 2.6075219 + 167000 42.33775 888 -0 2.6232299 + 168000 42.701344 888 -0 2.6389378 + 169000 43.067663 888 -0 2.6546458 + 170000 43.461687 1000 -0 2.6703538 + 171000 43.866086 1000 -0 2.6860617 + 172000 44.271406 1000 -0 2.7017697 + 173000 44.677085 1000 -0 2.7174776 + 174000 45.082441 1000 -0 2.7331856 + 175000 45.491593 1000 -0 2.7488936 + 176000 45.903002 1000 -0 2.7646015 + 177000 46.315031 1000 -0 2.7803095 + 178000 46.726531 1000 -0 2.7960175 + 179000 47.140818 1000 -0 2.8117254 + 180000 47.553784 1000 -0 2.8274334 + 181000 47.964021 1000 -0 2.8431414 + 182000 48.376739 1000 -0 2.8588493 + 183000 48.789612 1000 -0 2.8745573 + 184000 49.204073 1000 -0 2.8902652 + 185000 49.642401 1000 -0 2.9059732 + 186000 50.083479 1000 -0 2.9216812 + 187000 50.523357 1000 -0 2.9373891 + 188000 50.963685 1000 -0 2.9530971 + 189000 51.404166 1000 -0 2.9688051 + 190000 51.849094 1000 -0 2.984513 + 191000 52.291805 1000 -0 3.000221 + 192000 52.731855 1000 -0 3.0159289 + 193000 53.174104 1000 -0 3.0316369 + 194000 53.619739 1000 -0 3.0473449 + 195000 54.061019 1000 -0 3.0630528 + 196000 54.501149 1000 -0 3.0787608 + 197000 54.940486 1000 -0 3.0944688 + 198000 55.381843 1000 -0 3.1101767 + 199000 55.822243 1000 -0 3.1258847 + 200000 56.264319 1000 -0 3.1415927 +Loop time of 56.2643 on 1 procs for 200000 steps with 1000 atoms + +Performance: 14511.970 tau/day, 3554.650 timesteps/s +99.9% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 4.6309 | 4.6309 | 4.6309 | 0.0 | 8.23 +Neigh | 0.071456 | 0.071456 | 0.071456 | 0.0 | 0.13 +Comm | 0.50064 | 0.50064 | 0.50064 | 0.0 | 0.89 +Output | 0.0039163 | 0.0039163 | 0.0039163 | 0.0 | 0.01 +Modify | 50.189 | 50.189 | 50.189 | 0.0 | 89.20 +Other | | 0.8688 | | | 1.54 + +Nlocal: 1000 ave 1000 max 1000 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 183 ave 183 max 183 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 3926 ave 3926 max 3926 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 3926 +Ave neighs/atom = 3.926 +Neighbor list builds = 217 +Dangerous builds = 0 +unfix ins +run 200000 +Neighbor list info ... + 2 neighbor list requests + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 1.79826 + ghost atom cutoff = 1.79826 + binsize = 0.899132 -> bins = 23 23 23 +Memory usage per processor = 8.62017 Mbytes +Step CPU Atoms KinEng v_theta + 200000 0 1000 0.90078559 3.1415927 + 201000 0.44072509 1000 0.90377135 3.1573006 + 202000 0.8800211 1000 0.89194106 3.1730086 + 203000 1.3210881 1000 0.8940532 3.1887165 + 204000 1.762887 1000 0.8967696 3.2044245 + 205000 2.2080901 1000 0.89758718 3.2201325 + 206000 2.6548181 1000 0.89434418 3.2358404 + 207000 3.1002531 1000 0.87633906 3.2515484 + 208000 3.547334 1000 0.86721615 3.2672564 + 209000 3.993988 1000 0.86214817 3.2829643 + 210000 4.4423161 1000 0.85463743 3.2986723 + 211000 4.889446 1000 0.85744914 3.3143802 + 212000 5.3357229 1000 0.84702799 3.3300882 + 213000 5.780273 1000 0.84375104 3.3457962 + 214000 6.2249129 1000 0.83820701 3.3615041 + 215000 6.670651 1000 0.83566708 3.3772121 + 216000 7.113143 1000 0.83620798 3.3929201 + 217000 7.5359521 1000 0.83581605 3.408628 + 218000 7.9623129 1000 0.84045719 3.424336 + 219000 8.3878851 1000 0.85410521 3.440044 + 220000 8.8153811 1000 0.84336839 3.4557519 + 221000 9.244349 1000 0.85145747 3.4714599 + 222000 9.6728511 1000 0.8476916 3.4871678 + 223000 10.104052 1000 0.8412701 3.5028758 + 224000 10.532736 1000 0.8390277 3.5185838 + 225000 10.959564 1000 0.8359107 3.5342917 + 226000 11.38617 1000 0.83920631 3.5499997 + 227000 11.814104 1000 0.83930526 3.5657077 + 228000 12.241758 1000 0.83152308 3.5814156 + 229000 12.67198 1000 0.81211079 3.5971236 + 230000 13.101597 1000 0.80395018 3.6128316 + 231000 13.532943 1000 0.79991397 3.6285395 + 232000 13.969412 1000 0.80828959 3.6442475 + 233000 14.403885 1000 0.80892923 3.6599554 + 234000 14.833452 1000 0.82048914 3.6756634 + 235000 15.266211 1000 0.8174713 3.6913714 + 236000 15.697822 1000 0.81898551 3.7070793 + 237000 16.133023 1000 0.82034714 3.7227873 + 238000 16.569559 1000 0.81950728 3.7384953 + 239000 17.006308 1000 0.82152915 3.7542032 + 240000 17.445493 1000 0.83217597 3.7699112 + 241000 17.885585 1000 0.83464253 3.7856191 + 242000 18.324268 1000 0.84326166 3.8013271 + 243000 18.763748 1000 0.84235055 3.8170351 + 244000 19.203869 1000 0.83325408 3.832743 + 245000 19.645 1000 0.82577315 3.848451 + 246000 20.08666 1000 0.83923456 3.864159 + 247000 20.530596 1000 0.84153419 3.8798669 + 248000 20.971984 1000 0.85768309 3.8955749 + 249000 21.413571 1000 0.86910799 3.9112829 + 250000 21.854153 1000 0.8775521 3.9269908 + 251000 22.302884 1000 0.87299296 3.9426988 + 252000 22.753789 1000 0.86613861 3.9584067 + 253000 23.202458 1000 0.85513456 3.9741147 + 254000 23.655372 1000 0.84629733 3.9898227 + 255000 24.108225 1000 0.84154885 4.0055306 + 256000 24.561535 1000 0.84162715 4.0212386 + 257000 25.012338 1000 0.83959672 4.0369466 + 258000 25.466506 1000 0.83577695 4.0526545 + 259000 25.919168 1000 0.83021368 4.0683625 + 260000 26.37215 1000 0.81106893 4.0840704 + 261000 26.823834 1000 0.79884608 4.0997784 + 262000 27.276505 1000 0.78360303 4.1154864 + 263000 27.728503 1000 0.77030843 4.1311943 + 264000 28.181969 1000 0.76127974 4.1469023 + 265000 28.636329 1000 0.75553065 4.1626103 + 266000 29.090593 1000 0.75332019 4.1783182 + 267000 29.549547 1000 0.74670528 4.1940262 + 268000 30.008774 1000 0.74216141 4.2097342 + 269000 30.463826 1000 0.74564756 4.2254421 + 270000 30.920159 1000 0.7416035 4.2411501 + 271000 31.377192 1000 0.73061389 4.256858 + 272000 31.836268 1000 0.71620113 4.272566 + 273000 32.291662 1000 0.70840181 4.288274 + 274000 32.743646 1000 0.70946906 4.3039819 + 275000 33.197723 1000 0.70418049 4.3196899 + 276000 33.651405 1000 0.69591327 4.3353979 + 277000 34.106289 1000 0.69499716 4.3511058 + 278000 34.564324 1000 0.69242545 4.3668138 + 279000 35.020887 1000 0.69690811 4.3825218 + 280000 35.478222 1000 0.70402124 4.3982297 + 281000 35.938226 1000 0.71936578 4.4139377 + 282000 36.39808 1000 0.72439386 4.4296456 + 283000 36.855587 1000 0.72221632 4.4453536 + 284000 37.309629 1000 0.70387029 4.4610616 + 285000 37.791869 1000 0.70505716 4.4767695 + 286000 38.277853 1000 0.70731734 4.4924775 + 287000 38.764774 1000 0.71149743 4.5081855 + 288000 39.24815 1000 0.70994023 4.5238934 + 289000 39.728005 1000 0.69794225 4.5396014 + 290000 40.206798 1000 0.6905751 4.5553093 + 291000 40.678802 1000 0.68652972 4.5710173 + 292000 41.147991 1000 0.6743341 4.5867253 + 293000 41.618836 1000 0.67357205 4.6024332 + 294000 42.08982 1000 0.66465346 4.6181412 + 295000 42.561323 1000 0.65587678 4.6338492 + 296000 43.034196 1000 0.65455827 4.6495571 + 297000 43.505748 1000 0.65135145 4.6652651 + 298000 43.975299 1000 0.65400349 4.6809731 + 299000 44.447556 1000 0.66186899 4.696681 + 300000 44.926073 1000 0.66844193 4.712389 + 301000 45.402658 1000 0.67720506 4.7280969 + 302000 45.880643 1000 0.68554918 4.7438049 + 303000 46.359444 1000 0.69321489 4.7595129 + 304000 46.841542 1000 0.70345329 4.7752208 + 305000 47.323539 1000 0.70172137 4.7909288 + 306000 47.809358 1000 0.70989191 4.8066368 + 307000 48.291664 1000 0.70546377 4.8223447 + 308000 48.770327 1000 0.70820389 4.8380527 + 309000 49.248974 1000 0.69637815 4.8537606 + 310000 49.72965 1000 0.68679532 4.8694686 + 311000 50.204503 1000 0.68824984 4.8851766 + 312000 50.683502 1000 0.68647935 4.9008845 + 313000 51.161407 1000 0.68289956 4.9165925 + 314000 51.638365 1000 0.68356788 4.9323005 + 315000 52.114341 1000 0.68269829 4.9480084 + 316000 52.590791 1000 0.67961769 4.9637164 + 317000 53.043198 1000 0.67437047 4.9794244 + 318000 53.499062 1000 0.66534726 4.9951323 + 319000 53.954004 1000 0.66052125 5.0108403 + 320000 54.409776 1000 0.65351962 5.0265482 + 321000 54.867935 1000 0.64155441 5.0422562 + 322000 55.324528 1000 0.63463177 5.0579642 + 323000 55.780399 1000 0.62945691 5.0736721 + 324000 56.239189 1000 0.63156746 5.0893801 + 325000 56.697767 1000 0.63883759 5.1050881 + 326000 57.155746 1000 0.64703516 5.120796 + 327000 57.618744 1000 0.65532057 5.136504 + 328000 58.083021 1000 0.66697061 5.152212 + 329000 58.547646 1000 0.66896271 5.1679199 + 330000 59.011518 1000 0.66551963 5.1836279 + 331000 59.478689 1000 0.65083894 5.1993358 + 332000 59.94887 1000 0.65171641 5.2150438 + 333000 60.416096 1000 0.65122777 5.2307518 + 334000 60.889826 1000 0.65844334 5.2464597 + 335000 61.363105 1000 0.66931264 5.2621677 + 336000 61.832482 1000 0.66847415 5.2778757 + 337000 62.300731 1000 0.65863495 5.2935836 + 338000 62.769011 1000 0.64977739 5.3092916 + 339000 63.232862 1000 0.6454395 5.3249995 + 340000 63.699228 1000 0.63484999 5.3407075 + 341000 64.165101 1000 0.62753448 5.3564155 + 342000 64.631118 1000 0.62781442 5.3721234 + 343000 65.099469 1000 0.63813963 5.3878314 + 344000 65.576568 1000 0.6485183 5.4035394 + 345000 66.054068 1000 0.67111606 5.4192473 + 346000 66.531747 1000 0.68435581 5.4349553 + 347000 67.007296 1000 0.69526046 5.4506633 + 348000 67.478242 1000 0.6876531 5.4663712 + 349000 67.944422 1000 0.67962108 5.4820792 + 350000 68.410281 1000 0.6800934 5.4977871 + 351000 68.862112 1000 0.67658657 5.5134951 + 352000 69.316476 1000 0.67043355 5.5292031 + 353000 69.76356 1000 0.66863154 5.544911 + 354000 70.212144 1000 0.65806572 5.560619 + 355000 70.658375 1000 0.6498301 5.576327 + 356000 71.103688 1000 0.64384284 5.5920349 + 357000 71.551545 1000 0.64228421 5.6077429 + 358000 72.001238 1000 0.6408188 5.6234508 + 359000 72.45158 1000 0.64388002 5.6391588 + 360000 72.906369 1000 0.64347896 5.6548668 + 361000 73.358316 1000 0.65055455 5.6705747 + 362000 73.814119 1000 0.65545061 5.6862827 + 363000 74.277034 1000 0.6667431 5.7019907 + 364000 74.737593 1000 0.6869856 5.7176986 + 365000 75.20209 1000 0.69651407 5.7334066 + 366000 75.667448 1000 0.70824091 5.7491146 + 367000 76.132389 1000 0.7144853 5.7648225 + 368000 76.596067 1000 0.71780876 5.7805305 + 369000 77.059749 1000 0.7159398 5.7962384 + 370000 77.519236 1000 0.70648968 5.8119464 + 371000 77.977404 1000 0.69796557 5.8276544 + 372000 78.434017 1000 0.69876891 5.8433623 + 373000 78.887217 1000 0.70908957 5.8590703 + 374000 79.341658 1000 0.70831124 5.8747783 + 375000 79.802381 1000 0.70631178 5.8904862 + 376000 80.265165 1000 0.70533876 5.9061942 + 377000 80.727821 1000 0.70097225 5.9219022 + 378000 81.187538 1000 0.70139806 5.9376101 + 379000 81.645627 1000 0.69691027 5.9533181 + 380000 82.105692 1000 0.69163881 5.969026 + 381000 82.56483 1000 0.68973183 5.984734 + 382000 83.025126 1000 0.68059207 6.000442 + 383000 83.482786 1000 0.68096466 6.0161499 + 384000 83.939808 1000 0.6698933 6.0318579 + 385000 84.418408 1000 0.66795846 6.0475659 + 386000 84.898757 1000 0.66153854 6.0632738 + 387000 85.376756 1000 0.66560025 6.0789818 + 388000 85.853575 1000 0.66671699 6.0946897 + 389000 86.32865 1000 0.66013733 6.1103977 + 390000 86.807772 1000 0.66181942 6.1261057 + 391000 87.290335 1000 0.66281334 6.1418136 + 392000 87.773899 1000 0.66657879 6.1575216 + 393000 88.248567 1000 0.66608992 6.1732296 + 394000 88.723817 1000 0.66128929 6.1889375 + 395000 89.200089 1000 0.65764538 6.2046455 + 396000 89.671826 1000 0.65073015 6.2203535 + 397000 90.142595 1000 0.64967355 6.2360614 + 398000 90.616654 1000 0.65193957 6.2517694 + 399000 91.093856 1000 0.64936977 6.2674773 + 400000 91.571678 1000 0.65849743 6.2831853 +Loop time of 91.5717 on 1 procs for 200000 steps with 1000 atoms + +Performance: 8916.580 tau/day, 2184.081 timesteps/s +99.9% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 13.827 | 13.827 | 13.827 | 0.0 | 15.10 +Neigh | 0.097679 | 0.097679 | 0.097679 | 0.0 | 0.11 +Comm | 1.5668 | 1.5668 | 1.5668 | 0.0 | 1.71 +Output | 0.0042615 | 0.0042615 | 0.0042615 | 0.0 | 0.00 +Modify | 74.804 | 74.804 | 74.804 | 0.0 | 81.69 +Other | | 1.273 | | | 1.39 + +Nlocal: 1000 ave 1000 max 1000 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 289 ave 289 max 289 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 5091 ave 5091 max 5091 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 5091 +Ave neighs/atom = 5.091 +Neighbor list builds = 160 +Dangerous builds = 0 +Total wall time: 0:02:27 diff --git a/examples/granregion/log.6Oct16.granregion.mixer.g++.4 b/examples/granregion/log.6Oct16.granregion.mixer.g++.4 new file mode 100644 index 000000000..726b31f8f --- /dev/null +++ b/examples/granregion/log.6Oct16.granregion.mixer.g++.4 @@ -0,0 +1,609 @@ +LAMMPS (5 Oct 2016) +variable name string mixer + +thermo_modify flush yes +variable seed equal 14314 + +############################################### +# Particle parameters +################################################ + +variable rlo equal 0.3 +variable rhi equal 0.6 +variable dlo equal 2.0*${rlo} +variable dlo equal 2.0*0.3 +variable dhi equal 2.0*${rhi} +variable dhi equal 2.0*0.6 +variable skin equal ${rhi} +variable skin equal 0.6 + +variable coeffRes equal 0.1 +variable coeffFric equal 0.5 + +variable kn equal 10^5 +variable kt equal 0.2*${kn} +variable kt equal 0.2*100000 + +variable gravity equal 1.0 +variable density equal 1.0 + +variable min_mass equal ${density}*4.0/3.0*PI*${rlo}*${rlo}*${rlo} +variable min_mass equal 1*4.0/3.0*PI*${rlo}*${rlo}*${rlo} +variable min_mass equal 1*4.0/3.0*PI*0.3*${rlo}*${rlo} +variable min_mass equal 1*4.0/3.0*PI*0.3*0.3*${rlo} +variable min_mass equal 1*4.0/3.0*PI*0.3*0.3*0.3 +variable a equal (-2.0*log(${coeffRes})/PI)^2 +variable a equal (-2.0*log(0.1)/PI)^2 +variable gamma_n equal sqrt($a*2*${kn}/${min_mass}/(1+0.25*$a)) +variable gamma_n equal sqrt(0.405284734569351*2*${kn}/${min_mass}/(1+0.25*$a)) +variable gamma_n equal sqrt(0.405284734569351*2*100000/${min_mass}/(1+0.25*$a)) +variable gamma_n equal sqrt(0.405284734569351*2*100000/0.113097335529233/(1+0.25*$a)) +variable gamma_n equal sqrt(0.405284734569351*2*100000/0.113097335529233/(1+0.25*0.405284734569351)) +variable gamma_t equal ${gamma_n}*0.5 +variable gamma_t equal 806.699778405191*0.5 + +variable tcol equal PI/sqrt(2*${kn}/${min_mass}-${gamma_n}/4.0) +variable tcol equal PI/sqrt(2*100000/${min_mass}-${gamma_n}/4.0) +variable tcol equal PI/sqrt(2*100000/0.113097335529233-${gamma_n}/4.0) +variable tcol equal PI/sqrt(2*100000/0.113097335529233-806.699778405191/4.0) + +variable dt equal ${tcol}*0.02 +variable dt equal 0.00236257621510454*0.02 +timestep ${dt} +timestep 4.72515243020908e-05 + +############################################### + +variable dumpfreq equal 1000 +variable logfreq equal 1000 + +newton on +atom_style sphere + +boundary p p f + +region boxreg block 0 20 0 20 0 20 +create_box 1 boxreg +Created orthogonal box = (0 0 0) to (20 20 20) + 1 by 2 by 2 MPI processor grid + +pair_style gran/hertz/history ${kn} ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 +pair_style gran/hertz/history 100000 ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 +pair_style gran/hertz/history 100000 20000 ${gamma_n} ${gamma_t} ${coeffFric} 1 +pair_style gran/hertz/history 100000 20000 806.699778405191 ${gamma_t} ${coeffFric} 1 +pair_style gran/hertz/history 100000 20000 806.699778405191 403.349889202595 ${coeffFric} 1 +pair_style gran/hertz/history 100000 20000 806.699778405191 403.349889202595 0.5 1 +pair_coeff * * + +neighbor ${skin} bin +neighbor 0.6 bin +thermo ${logfreq} +thermo 1000 + +comm_style brick +comm_modify mode multi group all vel yes +balance 1.1 shift xyz 20 1.1 +Neighbor list info ... + 2 neighbor list requests + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 0 + ghost atom cutoff = 0 + binsize = 20 -> bins = 1 1 1 +fix bal all balance 10000 1.1 shift xyz 20 1.01 + +####################### Options specific to pouring ######################### + +region insreg cylinder z 10 10 8 10 18 side in units box +region cylreg cylinder z 10 10 10 0 20 side in units box + +variable theta equal (step/400000)*2*PI + +region b1 block 2 18 9 11 0 4 side out rotate v_theta 10 10 0 0 0 1 units box +region b2 block 9 11 2 18 0 3.99999 side out rotate v_theta 10 10 0 0 0 1 units box + +region mixer intersect 3 cylreg b1 b2 side in + +fix grav all gravity ${gravity} vector 0 0 -1 +fix grav all gravity 1 vector 0 0 -1 +fix 1 all nve/sphere + +fix mixwall all wall/gran/region hertz/history ${kn} ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 region mixer +fix mixwall all wall/gran/region hertz/history 100000 ${kt} ${gamma_n} ${gamma_t} ${coeffFric} 1 region mixer +fix mixwall all wall/gran/region hertz/history 100000 20000 ${gamma_n} ${gamma_t} ${coeffFric} 1 region mixer +fix mixwall all wall/gran/region hertz/history 100000 20000 806.699778405191 ${gamma_t} ${coeffFric} 1 region mixer +fix mixwall all wall/gran/region hertz/history 100000 20000 806.699778405191 403.349889202595 ${coeffFric} 1 region mixer +fix mixwall all wall/gran/region hertz/history 100000 20000 806.699778405191 403.349889202595 0.5 1 region mixer + +fix ins all pour 1000 1 42424 region insreg diam range ${dlo} ${dhi} dens ${density} ${density} +fix ins all pour 1000 1 42424 region insreg diam range 0.6 ${dhi} dens ${density} ${density} +fix ins all pour 1000 1 42424 region insreg diam range 0.6 1.2 dens ${density} ${density} +fix ins all pour 1000 1 42424 region insreg diam range 0.6 1.2 dens 1 ${density} +fix ins all pour 1000 1 42424 region insreg diam range 0.6 1.2 dens 1 1 +Particle insertion: 444 every 84653 steps, 1000 by step 169307 + +#dump 1 all custom ${dumpfreq} ${name}_pour.dump # id type mass diameter x y z + +#dump 2 all image 4000 image.*.jpg type type # axes yes 0.8 0.02 view 60 -30 zoom 1.5 # box no 0.0 axes no 0.0 0.0 +#dump_modify 2 pad 6 + +thermo_style custom step cpu atoms ke v_theta +WARNING: New thermo_style command, previous thermo_modify settings will be lost (../output.cpp:690) +thermo_modify flush yes lost warn + +run 200000 +Neighbor list info ... + 2 neighbor list requests + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 1.8 + ghost atom cutoff = 1.8 + binsize = 0.9 -> bins = 23 23 23 +Memory usage per processor = 2.76258 Mbytes +Step CPU Atoms KinEng v_theta + 0 0 0 -0 0 + 1000 0.10398197 444 -0 0.015707963 + 2000 0.20485091 444 -0 0.031415927 + 3000 0.3069241 444 -0 0.04712389 + 4000 0.40875912 444 -0 0.062831853 + 5000 0.50989199 444 -0 0.078539816 + 6000 0.60949397 444 -0 0.09424778 + 7000 0.708915 444 -0 0.10995574 + 8000 0.80870605 444 -0 0.12566371 + 9000 0.90752602 444 -0 0.14137167 + 10000 1.0054469 444 -0 0.15707963 + 11000 1.072515 444 -0 0.1727876 + 12000 1.139096 444 -0 0.18849556 + 13000 1.2049479 444 -0 0.20420352 + 14000 1.2707851 444 -0 0.21991149 + 15000 1.3377919 444 -0 0.23561945 + 16000 1.405757 444 -0 0.25132741 + 17000 1.471797 444 -0 0.26703538 + 18000 1.538343 444 -0 0.28274334 + 19000 1.6035659 444 -0 0.2984513 + 20000 1.6690421 444 -0 0.31415927 + 21000 1.729399 444 -0 0.32986723 + 22000 1.7885301 444 -0 0.34557519 + 23000 1.8496239 444 -0 0.36128316 + 24000 1.913486 444 -0 0.37699112 + 25000 1.977428 444 -0 0.39269908 + 26000 2.04282 444 -0 0.40840704 + 27000 2.1089439 444 -0 0.42411501 + 28000 2.1759491 444 -0 0.43982297 + 29000 2.243813 444 -0 0.45553093 + 30000 2.312156 444 -0 0.4712389 + 31000 2.3742449 444 -0 0.48694686 + 32000 2.435447 444 -0 0.50265482 + 33000 2.495765 444 -0 0.51836279 + 34000 2.556865 444 -0 0.53407075 + 35000 2.6201291 444 -0 0.54977871 + 36000 2.6843281 444 -0 0.56548668 + 37000 2.7505059 444 -0 0.58119464 + 38000 2.817348 444 -0 0.5969026 + 39000 2.8837919 444 -0 0.61261057 + 40000 2.951216 444 -0 0.62831853 + 41000 3.012845 444 -0 0.64402649 + 42000 3.074688 444 -0 0.65973446 + 43000 3.13556 444 -0 0.67544242 + 44000 3.1965449 444 -0 0.69115038 + 45000 3.2582009 444 -0 0.70685835 + 46000 3.3201971 444 -0 0.72256631 + 47000 3.3819821 444 -0 0.73827427 + 48000 3.4455171 444 -0 0.75398224 + 49000 3.508738 444 -0 0.7696902 + 50000 3.5734961 444 -0 0.78539816 + 51000 3.6333289 444 -0 0.80110613 + 52000 3.694531 444 -0 0.81681409 + 53000 3.757041 444 -0 0.83252205 + 54000 3.820612 444 -0 0.84823002 + 55000 3.8852711 444 -0 0.86393798 + 56000 3.950211 444 -0 0.87964594 + 57000 4.015795 444 -0 0.89535391 + 58000 4.0818441 444 -0 0.91106187 + 59000 4.1476641 444 -0 0.92676983 + 60000 4.2141221 444 -0 0.9424778 + 61000 4.276612 444 -0 0.95818576 + 62000 4.339952 444 -0 0.97389372 + 63000 4.404351 444 -0 0.98960169 + 64000 4.4700999 444 -0 1.0053096 + 65000 4.5364759 444 -0 1.0210176 + 66000 4.605715 444 -0 1.0367256 + 67000 4.677629 444 -0 1.0524335 + 68000 4.7494669 444 -0 1.0681415 + 69000 4.8212609 444 -0 1.0838495 + 70000 4.894326 444 -0 1.0995574 + 71000 4.9639831 444 -0 1.1152654 + 72000 5.0345671 444 -0 1.1309734 + 73000 5.1048689 444 -0 1.1466813 + 74000 5.175498 444 -0 1.1623893 + 75000 5.2477591 444 -0 1.1780972 + 76000 5.3205409 444 -0 1.1938052 + 77000 5.394573 444 -0 1.2095132 + 78000 5.4685309 444 -0 1.2252211 + 79000 5.5431759 444 -0 1.2409291 + 80000 5.6212411 444 -0 1.2566371 + 81000 5.6890731 444 -0 1.272345 + 82000 5.7582159 444 -0 1.288053 + 83000 5.8298571 444 -0 1.303761 + 84000 5.9029069 444 -0 1.3194689 + 85000 6.0061591 888 -0 1.3351769 + 86000 6.1541281 888 -0 1.3508848 + 87000 6.3004079 888 -0 1.3665928 + 88000 6.4460659 888 -0 1.3823008 + 89000 6.591886 888 -0 1.3980087 + 90000 6.7376239 888 -0 1.4137167 + 91000 6.850734 888 -0 1.4294247 + 92000 6.9631939 888 -0 1.4451326 + 93000 7.0786369 888 -0 1.4608406 + 94000 7.1958089 888 -0 1.4765485 + 95000 7.3130219 888 -0 1.4922565 + 96000 7.430867 888 -0 1.5079645 + 97000 7.5498819 888 -0 1.5236724 + 98000 7.673686 888 -0 1.5393804 + 99000 7.7966969 888 -0 1.5550884 + 100000 7.921546 888 -0 1.5707963 + 101000 8.0396931 888 -0 1.5865043 + 102000 8.1583791 888 -0 1.6022123 + 103000 8.276613 888 -0 1.6179202 + 104000 8.3952639 888 -0 1.6336282 + 105000 8.514308 888 -0 1.6493361 + 106000 8.6361439 888 -0 1.6650441 + 107000 8.762326 888 -0 1.6807521 + 108000 8.8900061 888 -0 1.69646 + 109000 9.0179789 888 -0 1.712168 + 110000 9.1496761 888 -0 1.727876 + 111000 9.2728269 888 -0 1.7435839 + 112000 9.398078 888 -0 1.7592919 + 113000 9.519841 888 -0 1.7749998 + 114000 9.642343 888 -0 1.7907078 + 115000 9.7643859 888 -0 1.8064158 + 116000 9.8893411 888 -0 1.8221237 + 117000 10.01295 888 -0 1.8378317 + 118000 10.137574 888 -0 1.8535397 + 119000 10.263738 888 -0 1.8692476 + 120000 10.388673 888 -0 1.8849556 + 121000 10.507599 888 -0 1.9006636 + 122000 10.623901 888 -0 1.9163715 + 123000 10.740251 888 -0 1.9320795 + 124000 10.857467 888 -0 1.9477874 + 125000 10.975856 888 -0 1.9634954 + 126000 11.096002 888 -0 1.9792034 + 127000 11.217218 888 -0 1.9949113 + 128000 11.341925 888 -0 2.0106193 + 129000 11.467607 888 -0 2.0263273 + 130000 11.59517 888 -0 2.0420352 + 131000 11.71358 888 -0 2.0577432 + 132000 11.833024 888 -0 2.0734512 + 133000 11.954967 888 -0 2.0891591 + 134000 12.078482 888 -0 2.1048671 + 135000 12.202435 888 -0 2.120575 + 136000 12.327202 888 -0 2.136283 + 137000 12.453334 888 -0 2.151991 + 138000 12.583142 888 -0 2.1676989 + 139000 12.718396 888 -0 2.1834069 + 140000 12.854459 888 -0 2.1991149 + 141000 12.981024 888 -0 2.2148228 + 142000 13.108875 888 -0 2.2305308 + 143000 13.236802 888 -0 2.2462387 + 144000 13.36691 888 -0 2.2619467 + 145000 13.500126 888 -0 2.2776547 + 146000 13.633748 888 -0 2.2933626 + 147000 13.769077 888 -0 2.3090706 + 148000 13.90522 888 -0 2.3247786 + 149000 14.040417 888 -0 2.3404865 + 150000 14.176483 888 -0 2.3561945 + 151000 14.303389 888 -0 2.3719025 + 152000 14.432187 888 -0 2.3876104 + 153000 14.559857 888 -0 2.4033184 + 154000 14.691256 888 -0 2.4190263 + 155000 14.823413 888 -0 2.4347343 + 156000 14.956581 888 -0 2.4504423 + 157000 15.090666 888 -0 2.4661502 + 158000 15.228012 888 -0 2.4818582 + 159000 15.364569 888 -0 2.4975662 + 160000 15.501847 888 -0 2.5132741 + 161000 15.642772 888 -0 2.5289821 + 162000 15.783889 888 -0 2.54469 + 163000 15.926508 888 -0 2.560398 + 164000 16.07293 888 -0 2.576106 + 165000 16.221293 888 -0 2.5918139 + 166000 16.371738 888 -0 2.6075219 + 167000 16.523027 888 -0 2.6232299 + 168000 16.675525 888 -0 2.6389378 + 169000 16.830527 888 -0 2.6546458 + 170000 16.989955 1000 -0 2.6703538 + 171000 17.14772 1000 -0 2.6860617 + 172000 17.305565 1000 -0 2.7017697 + 173000 17.463517 1000 -0 2.7174776 + 174000 17.623862 1000 -0 2.7331856 + 175000 17.788165 1000 -0 2.7488936 + 176000 17.952028 1000 -0 2.7646015 + 177000 18.119269 1000 -0 2.7803095 + 178000 18.285714 1000 -0 2.7960175 + 179000 18.452439 1000 -0 2.8117254 + 180000 18.621119 1000 -0 2.8274334 + 181000 18.777982 1000 -0 2.8431414 + 182000 18.940248 1000 -0 2.8588493 + 183000 19.105385 1000 -0 2.8745573 + 184000 19.273934 1000 -0 2.8902652 + 185000 19.450922 1000 -0 2.9059732 + 186000 19.625563 1000 -0 2.9216812 + 187000 19.801329 1000 -0 2.9373891 + 188000 19.976869 1000 -0 2.9530971 + 189000 20.151134 1000 -0 2.9688051 + 190000 20.319214 1000 -0 2.984513 + 191000 20.485033 1000 -0 3.000221 + 192000 20.652254 1000 -0 3.0159289 + 193000 20.820876 1000 -0 3.0316369 + 194000 20.988597 1000 -0 3.0473449 + 195000 21.154705 1000 -0 3.0630528 + 196000 21.322634 1000 -0 3.0787608 + 197000 21.489394 1000 -0 3.0944688 + 198000 21.659512 1000 -0 3.1101767 + 199000 21.833228 1000 -0 3.1258847 + 200000 22.006487 1000 -0 3.1415927 +Loop time of 22.0065 on 4 procs for 200000 steps with 1000 atoms + +Performance: 37102.953 tau/day, 9088.222 timesteps/s +99.1% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.67692 | 1.166 | 1.6704 | 44.4 | 5.30 +Neigh | 0.01562 | 0.018723 | 0.0222 | 2.3 | 0.09 +Comm | 3.845 | 4.4454 | 5.0282 | 26.1 | 20.20 +Output | 0.0043464 | 0.0052906 | 0.0056455 | 0.8 | 0.02 +Modify | 12.239 | 13.152 | 14.347 | 25.1 | 59.76 +Other | | 3.22 | | | 14.63 + +Nlocal: 250 ave 257 max 244 min +Histogram: 1 1 0 0 0 0 1 0 0 1 +Nghost: 305.75 ave 372 max 242 min +Histogram: 1 0 0 1 0 1 0 0 0 1 +Neighs: 982.5 ave 1380 max 572 min +Histogram: 2 0 0 0 0 0 0 0 0 2 + +Total # of neighbors = 3930 +Ave neighs/atom = 3.93 +Neighbor list builds = 216 +Dangerous builds = 0 +unfix ins +run 200000 +Neighbor list info ... + 2 neighbor list requests + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 1.79826 + ghost atom cutoff = 1.79826 + binsize = 0.899132 -> bins = 23 23 23 +Memory usage per processor = 8.63577 Mbytes +Step CPU Atoms KinEng v_theta + 200000 0 1000 0.90316284 3.1415927 + 201000 0.16518497 1000 0.8867387 3.1573006 + 202000 0.33065486 1000 0.88745316 3.1730086 + 203000 0.4991529 1000 0.87793424 3.1887165 + 204000 0.6695168 1000 0.87009551 3.2044245 + 205000 0.83599901 1000 0.86431259 3.2201325 + 206000 1.001833 1000 0.85039776 3.2358404 + 207000 1.166487 1000 0.82897867 3.2515484 + 208000 1.3331649 1000 0.82069182 3.2672564 + 209000 1.5031869 1000 0.82349024 3.2829643 + 210000 1.6751509 1000 0.81859611 3.2986723 + 211000 1.846776 1000 0.82053992 3.3143802 + 212000 2.0198569 1000 0.82832647 3.3300882 + 213000 2.1932938 1000 0.82676865 3.3457962 + 214000 2.3676898 1000 0.82425781 3.3615041 + 215000 2.5424879 1000 0.83127148 3.3772121 + 216000 2.715348 1000 0.83925992 3.3929201 + 217000 2.8844988 1000 0.84390181 3.408628 + 218000 3.0485029 1000 0.85705713 3.424336 + 219000 3.211767 1000 0.85325946 3.440044 + 220000 3.3767338 1000 0.85641557 3.4557519 + 221000 3.5419538 1000 0.86922287 3.4714599 + 222000 3.710084 1000 0.89591143 3.4871678 + 223000 3.880873 1000 0.90395821 3.5028758 + 224000 4.054816 1000 0.91161431 3.5185838 + 225000 4.2260928 1000 0.92716425 3.5342917 + 226000 4.3996999 1000 0.91664886 3.5499997 + 227000 4.5679309 1000 0.9128853 3.5657077 + 228000 4.7353978 1000 0.91063998 3.5814156 + 229000 4.9045198 1000 0.90616712 3.5971236 + 230000 5.079206 1000 0.9042797 3.6128316 + 231000 5.252316 1000 0.91588137 3.6285395 + 232000 5.4218178 1000 0.92322871 3.6442475 + 233000 5.592988 1000 0.92370885 3.6599554 + 234000 5.753634 1000 0.91531408 3.6756634 + 235000 5.9159088 1000 0.91016621 3.6913714 + 236000 6.0817358 1000 0.89501073 3.7070793 + 237000 6.249059 1000 0.88504426 3.7227873 + 238000 6.4182718 1000 0.88268268 3.7384953 + 239000 6.5897119 1000 0.87811868 3.7542032 + 240000 6.758353 1000 0.88272663 3.7699112 + 241000 6.928581 1000 0.87751512 3.7856191 + 242000 7.0978079 1000 0.87017281 3.8013271 + 243000 7.268832 1000 0.86587613 3.8170351 + 244000 7.439904 1000 0.85157794 3.832743 + 245000 7.6105168 1000 0.8291738 3.848451 + 246000 7.7830069 1000 0.82315948 3.864159 + 247000 7.9578128 1000 0.81231703 3.8798669 + 248000 8.134944 1000 0.79931415 3.8955749 + 249000 8.3061719 1000 0.78877578 3.9112829 + 250000 8.476692 1000 0.78519942 3.9269908 + 251000 8.6525538 1000 0.78837716 3.9426988 + 252000 8.8288019 1000 0.79621044 3.9584067 + 253000 9.006846 1000 0.78744385 3.9741147 + 254000 9.1839809 1000 0.78810047 3.9898227 + 255000 9.3600328 1000 0.79053484 4.0055306 + 256000 9.538172 1000 0.79976932 4.0212386 + 257000 9.7188668 1000 0.81724577 4.0369466 + 258000 9.9032769 1000 0.81135963 4.0526545 + 259000 10.084928 1000 0.82017101 4.0683625 + 260000 10.266693 1000 0.82352898 4.0840704 + 261000 10.449515 1000 0.81662689 4.0997784 + 262000 10.630166 1000 0.82707216 4.1154864 + 263000 10.812056 1000 0.82001278 4.1311943 + 264000 10.991668 1000 0.81136264 4.1469023 + 265000 11.172162 1000 0.80507755 4.1626103 + 266000 11.353101 1000 0.80247583 4.1783182 + 267000 11.533476 1000 0.78870449 4.1940262 + 268000 11.716022 1000 0.77775428 4.2097342 + 269000 11.900351 1000 0.78170639 4.2254421 + 270000 12.083609 1000 0.78023258 4.2411501 + 271000 12.266298 1000 0.76257507 4.256858 + 272000 12.449454 1000 0.75871195 4.272566 + 273000 12.633748 1000 0.75909277 4.288274 + 274000 12.820916 1000 0.76329234 4.3039819 + 275000 13.004197 1000 0.76188557 4.3196899 + 276000 13.188507 1000 0.75974847 4.3353979 + 277000 13.372202 1000 0.75392834 4.3511058 + 278000 13.557712 1000 0.74837333 4.3668138 + 279000 13.747933 1000 0.74268307 4.3825218 + 280000 13.934871 1000 0.73840427 4.3982297 + 281000 14.11717 1000 0.73817851 4.4139377 + 282000 14.30208 1000 0.73666069 4.4296456 + 283000 14.485039 1000 0.74064713 4.4453536 + 284000 14.671087 1000 0.73916222 4.4610616 + 285000 14.863267 1000 0.73225442 4.4767695 + 286000 15.050005 1000 0.7312283 4.4924775 + 287000 15.234556 1000 0.72947519 4.5081855 + 288000 15.422593 1000 0.72469992 4.5238934 + 289000 15.609153 1000 0.70843645 4.5396014 + 290000 15.797906 1000 0.69731415 4.5553093 + 291000 15.983677 1000 0.69099822 4.5710173 + 292000 16.168935 1000 0.68855366 4.5867253 + 293000 16.355853 1000 0.69826256 4.6024332 + 294000 16.544831 1000 0.70211589 4.6181412 + 295000 16.733875 1000 0.7055847 4.6338492 + 296000 16.918698 1000 0.69692413 4.6495571 + 297000 17.100869 1000 0.68027227 4.6652651 + 298000 17.280404 1000 0.67254493 4.6809731 + 299000 17.46406 1000 0.67767946 4.696681 + 300000 17.652748 1000 0.68480172 4.712389 + 301000 17.84199 1000 0.67864643 4.7280969 + 302000 18.025759 1000 0.67656342 4.7438049 + 303000 18.208747 1000 0.67719641 4.7595129 + 304000 18.391225 1000 0.68049491 4.7752208 + 305000 18.576276 1000 0.68230722 4.7909288 + 306000 18.764125 1000 0.67985 4.8066368 + 307000 18.956063 1000 0.67790944 4.8223447 + 308000 19.147159 1000 0.6836647 4.8380527 + 309000 19.339173 1000 0.69705355 4.8537606 + 310000 19.530591 1000 0.69858847 4.8694686 + 311000 19.720214 1000 0.69448554 4.8851766 + 312000 19.907717 1000 0.68878539 4.9008845 + 313000 20.088793 1000 0.68810484 4.9165925 + 314000 20.268118 1000 0.68483484 4.9323005 + 315000 20.445564 1000 0.67732034 4.9480084 + 316000 20.627415 1000 0.67943319 4.9637164 + 317000 20.807826 1000 0.67326868 4.9794244 + 318000 20.983587 1000 0.67762092 4.9951323 + 319000 21.156655 1000 0.68914624 5.0108403 + 320000 21.331391 1000 0.69872806 5.0265482 + 321000 21.506313 1000 0.71510434 5.0422562 + 322000 21.679505 1000 0.71452122 5.0579642 + 323000 21.85396 1000 0.71765429 5.0736721 + 324000 22.02904 1000 0.72748838 5.0893801 + 325000 22.205191 1000 0.72974854 5.1050881 + 326000 22.38063 1000 0.73324928 5.120796 + 327000 22.555817 1000 0.72479525 5.136504 + 328000 22.729859 1000 0.71942855 5.152212 + 329000 22.903234 1000 0.71890587 5.1679199 + 330000 23.078575 1000 0.73495891 5.1836279 + 331000 23.252865 1000 0.74306733 5.1993358 + 332000 23.427175 1000 0.75274051 5.2150438 + 333000 23.604881 1000 0.75981346 5.2307518 + 334000 23.789045 1000 0.75410165 5.2464597 + 335000 23.971105 1000 0.74802374 5.2621677 + 336000 24.150954 1000 0.73111266 5.2778757 + 337000 24.331991 1000 0.72226021 5.2935836 + 338000 24.515157 1000 0.70866271 5.3092916 + 339000 24.69639 1000 0.70253496 5.3249995 + 340000 24.879524 1000 0.69381505 5.3407075 + 341000 25.061928 1000 0.68285569 5.3564155 + 342000 25.2437 1000 0.67262303 5.3721234 + 343000 25.423809 1000 0.67160137 5.3878314 + 344000 25.605531 1000 0.67658439 5.4035394 + 345000 25.78848 1000 0.67113748 5.4192473 + 346000 25.969866 1000 0.67506296 5.4349553 + 347000 26.152485 1000 0.67686518 5.4506633 + 348000 26.335445 1000 0.68878941 5.4663712 + 349000 26.522271 1000 0.70728493 5.4820792 + 350000 26.709942 1000 0.70870657 5.4977871 + 351000 26.889998 1000 0.71541489 5.5134951 + 352000 27.069872 1000 0.71827633 5.5292031 + 353000 27.249259 1000 0.7099127 5.544911 + 354000 27.428386 1000 0.70507946 5.560619 + 355000 27.607797 1000 0.70709703 5.576327 + 356000 27.788887 1000 0.70637714 5.5920349 + 357000 27.975344 1000 0.7088694 5.6077429 + 358000 28.164236 1000 0.70907948 5.6234508 + 359000 28.352999 1000 0.71504714 5.6391588 + 360000 28.539172 1000 0.71417205 5.6548668 + 361000 28.722691 1000 0.70716852 5.6705747 + 362000 28.906856 1000 0.70193967 5.6862827 + 363000 29.087598 1000 0.69786793 5.7019907 + 364000 29.268141 1000 0.68714789 5.7176986 + 365000 29.450765 1000 0.68170443 5.7334066 + 366000 29.633131 1000 0.67832571 5.7491146 + 367000 29.816219 1000 0.67809457 5.7648225 + 368000 29.999479 1000 0.66886004 5.7805305 + 369000 30.182675 1000 0.67233336 5.7962384 + 370000 30.36698 1000 0.67433369 5.8119464 + 371000 30.550787 1000 0.67478226 5.8276544 + 372000 30.736018 1000 0.67882814 5.8433623 + 373000 30.922576 1000 0.68494254 5.8590703 + 374000 31.107558 1000 0.69046765 5.8747783 + 375000 31.291329 1000 0.69398953 5.8904862 + 376000 31.474582 1000 0.68692367 5.9061942 + 377000 31.656979 1000 0.674184 5.9219022 + 378000 31.83851 1000 0.65899449 5.9376101 + 379000 32.019869 1000 0.65198402 5.9533181 + 380000 32.200375 1000 0.64366122 5.969026 + 381000 32.381651 1000 0.64443345 5.984734 + 382000 32.561897 1000 0.64655912 6.000442 + 383000 32.743947 1000 0.64894161 6.0161499 + 384000 32.927231 1000 0.65259561 6.0318579 + 385000 33.11882 1000 0.65230446 6.0475659 + 386000 33.311072 1000 0.64177598 6.0632738 + 387000 33.50435 1000 0.63900349 6.0789818 + 388000 33.695734 1000 0.64611067 6.0946897 + 389000 33.885915 1000 0.64943993 6.1103977 + 390000 34.076093 1000 0.66303716 6.1261057 + 391000 34.264909 1000 0.68916583 6.1418136 + 392000 34.45411 1000 0.71501556 6.1575216 + 393000 34.644116 1000 0.73685375 6.1732296 + 394000 34.834608 1000 0.74461041 6.1889375 + 395000 35.025693 1000 0.75251204 6.2046455 + 396000 35.217372 1000 0.75493054 6.2203535 + 397000 35.407008 1000 0.77028775 6.2360614 + 398000 35.594868 1000 0.7686439 6.2517694 + 399000 35.778411 1000 0.75167376 6.2674773 + 400000 35.962646 1000 0.73505917 6.2831853 +Loop time of 35.9627 on 4 procs for 200000 steps with 1000 atoms + +Performance: 22704.278 tau/day, 5561.323 timesteps/s +99.0% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 2.0549 | 3.4094 | 4.9773 | 72.1 | 9.48 +Neigh | 0.022087 | 0.026923 | 0.032716 | 2.9 | 0.07 +Comm | 7.3555 | 9.2143 | 10.854 | 53.0 | 25.62 +Output | 0.0046289 | 0.0058927 | 0.0071292 | 1.4 | 0.02 +Modify | 17.504 | 19.601 | 22.342 | 44.9 | 54.50 +Other | | 3.705 | | | 10.30 + +Nlocal: 250 ave 269 max 225 min +Histogram: 1 0 0 0 0 1 0 1 0 1 +Nghost: 408.5 ave 500 max 320 min +Histogram: 2 0 0 0 0 0 0 0 0 2 +Neighs: 1262.25 ave 1665 max 880 min +Histogram: 1 0 1 0 0 0 0 1 0 1 + +Total # of neighbors = 5049 +Ave neighs/atom = 5.049 +Neighbor list builds = 166 +Dangerous builds = 0 +Total wall time: 0:00:57 diff --git a/lib/colvars/colvarmodule.cpp b/lib/colvars/colvarmodule.cpp index 050d4a2b9..ee5db06e3 100644 --- a/lib/colvars/colvarmodule.cpp +++ b/lib/colvars/colvarmodule.cpp @@ -1,1561 +1,1561 @@ // -*- c++ -*- #include #include #include "colvarmodule.h" #include "colvarparse.h" #include "colvarproxy.h" #include "colvar.h" #include "colvarbias.h" #include "colvarbias_abf.h" #include "colvarbias_alb.h" #include "colvarbias_histogram.h" #include "colvarbias_meta.h" #include "colvarbias_restraint.h" #include "colvarscript.h" colvarmodule::colvarmodule(colvarproxy *proxy_in) { // pointer to the proxy object if (proxy == NULL) { proxy = proxy_in; parse = new colvarparse(); } else { // TODO relax this error to handle multiple molecules in VMD // once the module is not static anymore cvm::error("Error: trying to allocate the collective " "variable module twice.\n"); return; } cvm::log(cvm::line_marker); cvm::log("Initializing the collective variables module, version "+ cvm::to_str(COLVARS_VERSION)+".\n"); cvm::log("Please cite Fiorin et al, Mol Phys 2013:\n " "http://dx.doi.org/10.1080/00268976.2013.813594\n" "in any publication based on this calculation.\n"); if (proxy->smp_enabled() == COLVARS_OK) { cvm::log("SMP parallelism is available.\n"); } // set initial default values // "it_restart" will be set by the input state file, if any; // "it" should be updated by the proxy colvarmodule::it = colvarmodule::it_restart = 0; colvarmodule::it_restart_from_state_file = true; colvarmodule::use_scripted_forces = false; colvarmodule::b_analysis = false; colvarmodule::debug_gradients_step_size = 1.0e-07; colvarmodule::rotation::monitor_crossings = false; colvarmodule::rotation::crossing_threshold = 1.0e-02; colvarmodule::cv_traj_freq = 100; colvarmodule::restart_out_freq = proxy->restart_frequency(); // by default overwrite the existing trajectory file colvarmodule::cv_traj_append = false; } int colvarmodule::read_config_file(char const *config_filename) { cvm::log(cvm::line_marker); cvm::log("Reading new configuration from file \""+ std::string(config_filename)+"\":\n"); // open the configfile config_s.open(config_filename); if (!config_s.is_open()) { cvm::error("Error: in opening configuration file \""+ std::string(config_filename)+"\".\n", FILE_ERROR); return COLVARS_ERROR; } // read the config file into a string std::string conf = ""; std::string line; while (colvarparse::getline_nocomments(config_s, line)) { // Delete lines that contain only white space after removing comments if (line.find_first_not_of(colvarparse::white_space) != std::string::npos) conf.append(line+"\n"); } config_s.close(); return parse_config(conf); } int colvarmodule::read_config_string(std::string const &config_str) { cvm::log(cvm::line_marker); cvm::log("Reading new configuration:\n"); std::istringstream config_s(config_str); // strip the comments away std::string conf = ""; std::string line; while (colvarparse::getline_nocomments(config_s, line)) { // Delete lines that contain only white space after removing comments if (line.find_first_not_of(colvarparse::white_space) != std::string::npos) conf.append(line+"\n"); } return parse_config(conf); } int colvarmodule::parse_config(std::string &conf) { // parse global options if (catch_input_errors(parse_global_params(conf))) { return get_error(); } // parse the options for collective variables if (catch_input_errors(parse_colvars(conf))) { return get_error(); } // parse the options for biases if (catch_input_errors(parse_biases(conf))) { return get_error(); } // done parsing known keywords, check that all keywords found were valid ones if (catch_input_errors(parse->check_keywords(conf, "colvarmodule"))) { return get_error(); } cvm::log(cvm::line_marker); cvm::log("Collective variables module (re)initialized.\n"); cvm::log(cvm::line_marker); // update any necessary proxy data proxy->setup(); if (cv_traj_os.is_open()) { // configuration might have changed, better redo the labels write_traj_label(cv_traj_os); } return get_error(); } int colvarmodule::parse_global_params(std::string const &conf) { std::string index_file_name; if (parse->get_keyval(conf, "indexFile", index_file_name)) { read_index_file(index_file_name.c_str()); } parse->get_keyval(conf, "analysis", b_analysis, b_analysis); parse->get_keyval(conf, "debugGradientsStepSize", debug_gradients_step_size, debug_gradients_step_size, colvarparse::parse_silent); parse->get_keyval(conf, "monitorEigenvalueCrossing", colvarmodule::rotation::monitor_crossings, colvarmodule::rotation::monitor_crossings, colvarparse::parse_silent); parse->get_keyval(conf, "eigenvalueCrossingThreshold", colvarmodule::rotation::crossing_threshold, colvarmodule::rotation::crossing_threshold, colvarparse::parse_silent); parse->get_keyval(conf, "colvarsTrajFrequency", cv_traj_freq, cv_traj_freq); parse->get_keyval(conf, "colvarsRestartFrequency", restart_out_freq, restart_out_freq); // if this is true when initializing, it means // we are continuing after a reset(): default to true parse->get_keyval(conf, "colvarsTrajAppend", cv_traj_append, cv_traj_append); parse->get_keyval(conf, "scriptedColvarForces", use_scripted_forces, false); parse->get_keyval(conf, "scriptingAfterBiases", scripting_after_biases, true); if (use_scripted_forces && !proxy->force_script_defined) { cvm::error("User script for scripted colvar forces not found.", INPUT_ERROR); } return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } int colvarmodule::parse_colvars(std::string const &conf) { if (cvm::debug()) cvm::log("Initializing the collective variables.\n"); std::string colvar_conf = ""; size_t pos = 0; while (parse->key_lookup(conf, "colvar", colvar_conf, pos)) { if (colvar_conf.size()) { cvm::log(cvm::line_marker); cvm::increase_depth(); colvars.push_back(new colvar(colvar_conf)); if (cvm::get_error() || ((colvars.back())->check_keywords(colvar_conf, "colvar") != COLVARS_OK)) { cvm::log("Error while constructing colvar number " + cvm::to_str(colvars.size()) + " : deleting."); delete colvars.back(); // the colvar destructor updates the colvars array return COLVARS_ERROR; } cvm::decrease_depth(); } else { cvm::error("Error: \"colvar\" keyword found without any configuration.\n", INPUT_ERROR); return COLVARS_ERROR; } cvm::decrease_depth(); colvar_conf = ""; } if (!colvars.size()) { cvm::log("Warning: no collective variables defined.\n"); } if (colvars.size()) cvm::log(cvm::line_marker); cvm::log("Collective variables initialized, "+ cvm::to_str(colvars.size())+ " in total.\n"); return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } bool colvarmodule::check_new_bias(std::string &conf, char const *key) { if (cvm::get_error() || (biases.back()->check_keywords(conf, key) != COLVARS_OK)) { cvm::log("Error while constructing bias number " + cvm::to_str(biases.size()) + " : deleting.\n"); delete biases.back(); // the bias destructor updates the biases array return true; } return false; } template int colvarmodule::parse_biases_type(std::string const &conf, char const *keyword, size_t &bias_count) { std::string bias_conf = ""; size_t conf_saved_pos = 0; while (parse->key_lookup(conf, keyword, bias_conf, conf_saved_pos)) { if (bias_conf.size()) { cvm::log(cvm::line_marker); cvm::increase_depth(); biases.push_back(new bias_type(keyword)); biases.back()->init(bias_conf); if (cvm::check_new_bias(bias_conf, keyword) != COLVARS_OK) { return COLVARS_ERROR; } cvm::decrease_depth(); bias_count++; } else { cvm::error("Error: keyword \""+std::string(keyword)+"\" found without configuration.\n", INPUT_ERROR); return COLVARS_ERROR; } bias_conf = ""; } return COLVARS_OK; } int colvarmodule::parse_biases(std::string const &conf) { if (cvm::debug()) cvm::log("Initializing the collective variables biases.\n"); /// initialize ABF instances parse_biases_type(conf, "abf", n_abf_biases); /// initialize adaptive linear biases parse_biases_type(conf, "ALB", n_rest_biases); /// initialize harmonic restraints parse_biases_type(conf, "harmonic", n_rest_biases); /// initialize histograms parse_biases_type(conf, "histogram", n_histo_biases); /// initialize histogram restraints parse_biases_type(conf, "histogramRestraint", n_rest_biases); /// initialize linear restraints parse_biases_type(conf, "linear", n_rest_biases); /// initialize metadynamics instances parse_biases_type(conf, "metadynamics", n_meta_biases); if (use_scripted_forces) { cvm::log(cvm::line_marker); cvm::increase_depth(); cvm::log("User forces script will be run at each bias update."); cvm::decrease_depth(); } size_t i; for (i = 0; i < biases.size(); i++) { biases[i]->enable(colvardeps::f_cvb_active); if (cvm::debug()) biases[i]->print_state(); } size_t n_hist_dep_biases = 0; std::vector hist_dep_biases_names; for (i = 0; i < biases.size(); i++) { if (biases[i]->is_enabled(colvardeps::f_cvb_apply_force) && biases[i]->is_enabled(colvardeps::f_cvb_history_dependent)) { n_hist_dep_biases++; hist_dep_biases_names.push_back(biases[i]->name); } } if (n_hist_dep_biases > 1) { cvm::log("WARNING: there are "+cvm::to_str(n_hist_dep_biases)+ " history-dependent biases with non-zero force parameters:\n"+ cvm::to_str(hist_dep_biases_names)+"\n"+ "Please make sure that their forces do not counteract each other.\n"); } if (biases.size() || use_scripted_forces) { cvm::log(cvm::line_marker); cvm::log("Collective variables biases initialized, "+ cvm::to_str(biases.size())+" in total.\n"); } else { if (!use_scripted_forces) { cvm::log("No collective variables biases were defined.\n"); } } return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } int colvarmodule::catch_input_errors(int result) { if (result != COLVARS_OK || get_error()) { set_error_bits(result); set_error_bits(INPUT_ERROR); parse->init(); return get_error(); } return COLVARS_OK; } colvarbias * colvarmodule::bias_by_name(std::string const &name) { for (std::vector::iterator bi = biases.begin(); bi != biases.end(); bi++) { if ((*bi)->name == name) { return (*bi); } } return NULL; } colvar *colvarmodule::colvar_by_name(std::string const &name) { for (std::vector::iterator cvi = colvars.begin(); cvi != colvars.end(); cvi++) { if ((*cvi)->name == name) { return (*cvi); } } return NULL; } int colvarmodule::change_configuration(std::string const &bias_name, std::string const &conf) { // This is deprecated; supported strategy is to delete the bias // and parse the new config cvm::increase_depth(); colvarbias *b; b = bias_by_name(bias_name); if (b == NULL) { cvm::error("Error: bias not found: " + bias_name); } b->change_configuration(conf); cvm::decrease_depth(); return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } std::string colvarmodule::read_colvar(std::string const &name) { cvm::increase_depth(); colvar *c; std::stringstream ss; c = colvar_by_name(name); if (c == NULL) { cvm::fatal_error("Error: colvar not found: " + name); } ss << c->value(); cvm::decrease_depth(); return ss.str(); } cvm::real colvarmodule::energy_difference(std::string const &bias_name, std::string const &conf) { cvm::increase_depth(); colvarbias *b; cvm::real energy_diff = 0.; b = bias_by_name(bias_name); if (b == NULL) { cvm::fatal_error("Error: bias not found: " + bias_name); } energy_diff = b->energy_difference(conf); cvm::decrease_depth(); return energy_diff; } int colvarmodule::bias_current_bin(std::string const &bias_name) { cvm::increase_depth(); int ret; colvarbias *b = bias_by_name(bias_name); if (b != NULL) { ret = b->current_bin(); } else { cvm::error("Error: bias not found.\n"); ret = COLVARS_ERROR; } cvm::decrease_depth(); return ret; } int colvarmodule::bias_bin_num(std::string const &bias_name) { cvm::increase_depth(); int ret; colvarbias *b = bias_by_name(bias_name); if (b != NULL) { ret = b->bin_num(); } else { cvm::error("Error: bias not found.\n"); ret = COLVARS_ERROR; } cvm::decrease_depth(); return ret; } int colvarmodule::bias_bin_count(std::string const &bias_name, size_t bin_index) { cvm::increase_depth(); int ret; colvarbias *b = bias_by_name(bias_name); if (b != NULL) { ret = b->bin_count(bin_index); } else { cvm::error("Error: bias not found.\n"); ret = COLVARS_ERROR; } cvm::decrease_depth(); return ret; } int colvarmodule::bias_share(std::string const &bias_name) { cvm::increase_depth(); int ret; colvarbias *b = bias_by_name(bias_name); if (b != NULL) { b->replica_share(); ret = COLVARS_OK; } else { cvm::error("Error: bias not found.\n"); ret = COLVARS_ERROR; } cvm::decrease_depth(); return ret; } int colvarmodule::calc() { int error_code = COLVARS_OK; if (cvm::debug()) { cvm::log(cvm::line_marker); cvm::log("Collective variables module, step no. "+ cvm::to_str(cvm::step_absolute())+"\n"); } error_code |= calc_colvars(); // set biasing forces to zero before biases are calculated and summed over for (std::vector::iterator cvi = colvars.begin(); cvi != colvars.end(); cvi++) { (*cvi)->reset_bias_force(); } error_code |= calc_biases(); error_code |= update_colvar_forces(); if (cvm::b_analysis) { error_code |= analyze(); } // write trajectory files, if needed if (cv_traj_freq && cv_traj_name.size()) { error_code |= write_traj_files(); } // write restart files, if needed if (restart_out_freq && restart_out_name.size()) { error_code |= write_restart_files(); } return error_code; } int colvarmodule::calc_colvars() { if (cvm::debug()) cvm::log("Calculating collective variables.\n"); // calculate collective variables and their gradients int error_code = COLVARS_OK; std::vector::iterator cvi; // Determine which colvars are active at this time step for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) { (*cvi)->feature_states[colvardeps::f_cv_active]->enabled = (step_absolute() % (*cvi)->get_time_step_factor() == 0); } // if SMP support is available, split up the work if (proxy->smp_enabled() == COLVARS_OK) { // first, calculate how much work (currently, how many active CVCs) each colvar has colvars_smp.resize(0); colvars_smp_items.resize(0); colvars_smp.reserve(colvars.size()); colvars_smp_items.reserve(colvars.size()); // set up a vector containing all components size_t num_colvar_items = 0; cvm::increase_depth(); for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) { if (!(*cvi)->is_enabled()) continue; error_code |= (*cvi)->update_cvc_flags(); size_t num_items = (*cvi)->num_active_cvcs(); colvars_smp.reserve(colvars_smp.size() + num_items); colvars_smp_items.reserve(colvars_smp_items.size() + num_items); for (size_t icvc = 0; icvc < num_items; icvc++) { colvars_smp.push_back(*cvi); colvars_smp_items.push_back(icvc); } num_colvar_items += num_items; } cvm::decrease_depth(); // calculate colvar components in parallel error_code |= proxy->smp_colvars_loop(); cvm::increase_depth(); for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) { if (!(*cvi)->is_enabled()) continue; error_code |= (*cvi)->collect_cvc_data(); } cvm::decrease_depth(); } else { // calculate colvars one at a time cvm::increase_depth(); for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) { if (!(*cvi)->is_enabled()) continue; error_code |= (*cvi)->calc(); if (cvm::get_error()) { return COLVARS_ERROR; } } cvm::decrease_depth(); } error_code |= cvm::get_error(); return error_code; } int colvarmodule::calc_biases() { // update the biases and communicate their forces to the collective // variables if (cvm::debug() && biases.size()) cvm::log("Updating collective variable biases.\n"); std::vector::iterator bi; int error_code = COLVARS_OK; // if SMP support is available, split up the work if (proxy->smp_enabled() == COLVARS_OK) { if (use_scripted_forces && !scripting_after_biases) { // calculate biases and scripted forces in parallel error_code |= proxy->smp_biases_script_loop(); } else { // calculate biases in parallel error_code |= proxy->smp_biases_loop(); } } else { if (use_scripted_forces && !scripting_after_biases) { error_code |= calc_scripted_forces(); } cvm::increase_depth(); for (bi = biases.begin(); bi != biases.end(); bi++) { error_code |= (*bi)->update(); if (cvm::get_error()) { return COLVARS_ERROR; } } cvm::decrease_depth(); } cvm::real total_bias_energy = 0.0; for (bi = biases.begin(); bi != biases.end(); bi++) { total_bias_energy += (*bi)->get_energy(); } proxy->add_energy(total_bias_energy); return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } int colvarmodule::update_colvar_forces() { int error_code = COLVARS_OK; std::vector::iterator cvi; std::vector::iterator bi; // sum the forces from all biases for each collective variable if (cvm::debug() && biases.size()) cvm::log("Collecting forces from all biases.\n"); cvm::increase_depth(); for (bi = biases.begin(); bi != biases.end(); bi++) { (*bi)->communicate_forces(); if (cvm::get_error()) { return COLVARS_ERROR; } } cvm::decrease_depth(); if (use_scripted_forces && scripting_after_biases) { error_code |= calc_scripted_forces(); } cvm::real total_colvar_energy = 0.0; // sum up the forces for each colvar, including wall forces // and integrate any internal // equation of motion (extended system) if (cvm::debug()) cvm::log("Updating the internal degrees of freedom " "of colvars (if they have any).\n"); cvm::increase_depth(); for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) { // Here we call even inactive colvars, so they accumulate biasing forces // as well as update their extended-system dynamics total_colvar_energy += (*cvi)->update_forces_energy(); if (cvm::get_error()) { return COLVARS_ERROR; } } cvm::decrease_depth(); proxy->add_energy(total_colvar_energy); // make collective variables communicate their forces to their // coupled degrees of freedom (i.e. atoms) if (cvm::debug()) cvm::log("Communicating forces from the colvars to the atoms.\n"); cvm::increase_depth(); for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) { if ((*cvi)->is_enabled(colvardeps::f_cv_gradient)) { if (!(*cvi)->is_enabled()) continue; (*cvi)->communicate_forces(); if (cvm::get_error()) { return COLVARS_ERROR; } } } cvm::decrease_depth(); return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } int colvarmodule::calc_scripted_forces() { // Run user force script, if provided, // potentially adding scripted forces to the colvars int res; res = proxy->run_force_callback(); if (res == COLVARS_NOT_IMPLEMENTED) { cvm::error("Colvar forces scripts are not implemented."); return COLVARS_NOT_IMPLEMENTED; } if (res != COLVARS_OK) { cvm::error("Error running user colvar forces script"); return COLVARS_ERROR; } return COLVARS_OK; } int colvarmodule::write_restart_files() { if ( (cvm::step_relative() > 0) && ((cvm::step_absolute() % restart_out_freq) == 0) ) { cvm::log("Writing the state file \""+ restart_out_name+"\".\n"); proxy->backup_file(restart_out_name.c_str()); restart_out_os.open(restart_out_name.c_str()); if (!restart_out_os.is_open() || !write_restart(restart_out_os)) cvm::error("Error: in writing restart file.\n"); restart_out_os.close(); } return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } int colvarmodule::write_traj_files() { if (!cv_traj_os.is_open()) { open_traj_file(cv_traj_name); } // write labels in the traj file every 1000 lines and at first timestep if ((cvm::step_absolute() % (cv_traj_freq * 1000)) == 0 || cvm::step_relative() == 0) { write_traj_label(cv_traj_os); } if ((cvm::step_absolute() % cv_traj_freq) == 0) { write_traj(cv_traj_os); } if (restart_out_freq && cv_traj_os.is_open()) { // flush the trajectory file if we are at the restart frequency if ( (cvm::step_relative() > 0) && ((cvm::step_absolute() % restart_out_freq) == 0) ) { cvm::log("Synchronizing (emptying the buffer of) trajectory file \""+ cv_traj_name+"\".\n"); cv_traj_os.flush(); } } return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } int colvarmodule::analyze() { if (cvm::debug()) { cvm::log("colvarmodule::analyze(), step = "+cvm::to_str(it)+".\n"); } if (cvm::step_relative() == 0) cvm::log("Performing analysis.\n"); // perform colvar-specific analysis for (std::vector::iterator cvi = colvars.begin(); cvi != colvars.end(); cvi++) { cvm::increase_depth(); (*cvi)->analyze(); cvm::decrease_depth(); } // perform bias-specific analysis for (std::vector::iterator bi = biases.begin(); bi != biases.end(); bi++) { cvm::increase_depth(); (*bi)->analyze(); cvm::decrease_depth(); } return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } int colvarmodule::setup() { // loop over all components of all colvars to reset masses of all groups for (std::vector::iterator cvi = colvars.begin(); cvi != colvars.end(); cvi++) { (*cvi)->setup(); } return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } colvarmodule::~colvarmodule() { if ((proxy->smp_thread_id() == COLVARS_NOT_IMPLEMENTED) || (proxy->smp_thread_id() == 0)) { reset(); delete parse; parse = NULL; proxy = NULL; } } int colvarmodule::reset() { parse->init(); cvm::log("Resetting the Collective Variables Module.\n"); // Iterate backwards because we are deleting the elements as we go for (std::vector::reverse_iterator bi = biases.rbegin(); bi != biases.rend(); bi++) { delete *bi; // the bias destructor updates the biases array } biases.clear(); // Iterate backwards because we are deleting the elements as we go for (std::vector::reverse_iterator cvi = colvars.rbegin(); cvi != colvars.rend(); cvi++) { delete *cvi; // the colvar destructor updates the colvars array } colvars.clear(); index_groups.clear(); index_group_names.clear(); if (cv_traj_os.is_open()) { // Do not close file here, as we might not be done with it yet. cv_traj_os.flush(); } return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } int colvarmodule::setup_input() { // name of input state file restart_in_name = proxy->input_prefix().size() ? std::string(proxy->input_prefix()+".colvars.state") : std::string("") ; // read the restart configuration, if available if (restart_in_name.size()) { // read the restart file std::ifstream input_is(restart_in_name.c_str()); if (!input_is.good()) { cvm::error("Error: in opening restart file \""+ std::string(restart_in_name)+"\".\n", FILE_ERROR); return COLVARS_ERROR; } else { cvm::log("Restarting from file \""+restart_in_name+"\".\n"); read_restart(input_is); if (cvm::get_error() != COLVARS_OK) { return COLVARS_ERROR; } cvm::log(cvm::line_marker); } } return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } int colvarmodule::setup_output() { int error_code = 0; // output state file (restart) restart_out_name = proxy->restart_output_prefix().size() ? std::string(proxy->restart_output_prefix()+".colvars.state") : std::string(""); if (restart_out_name.size()) { cvm::log("The restart output state file will be \""+restart_out_name+"\".\n"); } output_prefix = proxy->output_prefix(); if (output_prefix.size()) { cvm::log("The final output state file will be \""+ (output_prefix.size() ? std::string(output_prefix+".colvars.state") : std::string("colvars.state"))+"\".\n"); // cvm::log (cvm::line_marker); } cv_traj_name = (output_prefix.size() ? std::string(output_prefix+".colvars.traj") : std::string("")); if (cv_traj_freq && cv_traj_name.size()) { error_code |= open_traj_file(cv_traj_name); } for (std::vector::iterator bi = biases.begin(); bi != biases.end(); bi++) { error_code |= (*bi)->setup_output(); } if (error_code != COLVARS_OK || cvm::get_error()) { set_error_bits(FILE_ERROR); } return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } std::istream & colvarmodule::read_restart(std::istream &is) { bool warn_total_forces = false; { // read global restart information std::string restart_conf; if (is >> colvarparse::read_block("configuration", restart_conf)) { if (it_restart_from_state_file) { parse->get_keyval(restart_conf, "step", it_restart, (size_t) 0, colvarparse::parse_silent); it = it_restart; } std::string restart_version; parse->get_keyval(restart_conf, "version", restart_version, std::string(""), colvarparse::parse_silent); if (restart_version.size() && (restart_version != std::string(COLVARS_VERSION))) { cvm::log("This state file was generated with version "+restart_version+"\n"); } if ((restart_version.size() == 0) || (restart_version.compare(std::string(COLVARS_VERSION)) < 0)) { // check for total force change if (proxy->total_forces_enabled()) { warn_total_forces = true; } } } is.clear(); parse->clear_keyword_registry(); } // colvars restart cvm::increase_depth(); for (std::vector::iterator cvi = colvars.begin(); cvi != colvars.end(); cvi++) { if ( !((*cvi)->read_restart(is)) ) { cvm::error("Error: in reading restart configuration for collective variable \""+ (*cvi)->name+"\".\n", INPUT_ERROR); } } // biases restart for (std::vector::iterator bi = biases.begin(); bi != biases.end(); bi++) { if (!((*bi)->read_restart(is))) { cvm::error("Error: in reading restart configuration for bias \""+ (*bi)->name+"\".\n", INPUT_ERROR); } } cvm::decrease_depth(); if (warn_total_forces) { cvm::log(cvm::line_marker); cvm::log("WARNING:\n"); std::string const warning("### CHANGES IN THE DEFINITION OF SYSTEM FORCES (NOW TOTAL FORCES)\n\ \n\ Starting from the version 2016-08-10 of the Colvars module, \n\ the role of system forces has been replaced by total forces.\n\ \n\ These include *all* forces acting on a collective variable, whether they\n\ come from the force field potential or from external terms\n\ (e.g. restraints), including forces applied by Colvars itself.\n\ \n\ In NAMD, forces applied by Colvars, IMD, SMD, TMD, symmetry\n\ restraints and tclForces are now all counted in the total force.\n\ \n\ In LAMMPS, forces applied by Colvars itself are now counted in the total\n\ force (all forces from other fixes were being counted already).\n\ \n\ \n\ ### WHEN IS THIS CHANGE RELEVANT\n\ \n\ This change affects results *only* when (1) outputSystemForce is\n\ requested or (2) the ABF bias is used. All other usage cases are\n\ *unaffected* (colvar restraints, metadynamics, etc).\n\ \n\ When system forces are reported (flag: outputSystemForce), their values\n\ in the output may change, but the physical trajectory is never affected.\n\ The physical results of ABF calculations may be affected in some cases.\n\ \n\ \n\ ### CHANGES TO ABF CALCULATIONS\n\ \n\ Compared to previous Colvars versions, the ABF method will now attempt\n\ to cancel external forces (for example, boundary walls) and it may be\n\ not possible to resume through a state file a simulation that was\n\ performed with a previous version.\n\ \n\ There are three possible scenarios:\n\ \n\ 1. No external forces are applied to the atoms used by ABF: results are\n\ unchanged.\n\ \n\ 2. Some of the atoms used by ABF experience external forces, but these\n\ forces are not applied directly to the variables used by ABF\n\ (e.g. another colvar that uses the same atoms, tclForces, etc): in this\n\ case, we recommend beginning a new simulation.\n\ \n\ 3. External forces are applied to one or more of the colvars used by\n\ ABF, but no other forces are applied to their atoms: you may use the\n\ subtractAppliedForce keyword inside the corresponding colvars to\n\ continue the previous simulation.\n\n"); cvm::log(warning); cvm::log(cvm::line_marker); // update this ahead of time in this special case output_prefix = proxy->output_prefix(); cvm::log("All output files will now be saved with the prefix \""+output_prefix+".tmp.*\".\n"); output_prefix = output_prefix+".tmp"; write_output_files(); cvm::log(cvm::line_marker); cvm::log("Please review the important warning above. After that, you may rename:\n\ \""+output_prefix+".tmp.colvars.state\"\n\ to:\n\ \""+output_prefix+".colvars.state\"\n"); cvm::error("Exiting with error until issue is addressed.\n", FATAL_ERROR); } return is; } int colvarmodule::backup_file(char const *filename) { return proxy->backup_file(filename); } int colvarmodule::write_output_files() { // if this is a simulation run (i.e. not a postprocessing), output data // must be written to be able to restart the simulation std::string const out_name = (output_prefix.size() ? std::string(output_prefix+".colvars.state") : std::string("colvars.state")); cvm::log("Saving collective variables state to \""+out_name+"\".\n"); std::ostream * os = proxy->output_stream(out_name); os->setf(std::ios::scientific, std::ios::floatfield); this->write_restart(*os); proxy->close_output_stream(out_name); cvm::increase_depth(); for (std::vector::iterator cvi = colvars.begin(); cvi != colvars.end(); cvi++) { (*cvi)->write_output_files(); } cvm::decrease_depth(); cvm::increase_depth(); for (std::vector::iterator bi = biases.begin(); bi != biases.end(); bi++) { (*bi)->write_output_files(); } cvm::decrease_depth(); if (cv_traj_os.is_open()) { // do not close to avoid problems with multiple NAMD runs cv_traj_os.flush(); } return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } int colvarmodule::read_traj(char const *traj_filename, long traj_read_begin, long traj_read_end) { cvm::log("Opening trajectory file \""+ std::string(traj_filename)+"\".\n"); std::ifstream traj_is(traj_filename); while (true) { while (true) { std::string line(""); do { if (!colvarparse::getline_nocomments(traj_is, line)) { cvm::log("End of file \""+std::string(traj_filename)+ "\" reached, or corrupted file.\n"); traj_is.close(); return false; } } while (line.find_first_not_of(colvarparse::white_space) == std::string::npos); std::istringstream is(line); if (!(is >> it)) return false; if ( (it < traj_read_begin) ) { if ((it % 1000) == 0) std::cerr << "Skipping trajectory step " << it << " \r"; continue; } else { if ((it % 1000) == 0) std::cerr << "Reading from trajectory, step = " << it << " \r"; if ( (traj_read_end > traj_read_begin) && (it > traj_read_end) ) { std::cerr << "\n"; cvm::error("Reached the end of the trajectory, " "read_end = "+cvm::to_str(traj_read_end)+"\n", FILE_ERROR); return COLVARS_ERROR; } for (std::vector::iterator cvi = colvars.begin(); cvi != colvars.end(); cvi++) { if (!(*cvi)->read_traj(is)) { cvm::error("Error: in reading colvar \""+(*cvi)->name+ "\" from trajectory file \""+ std::string(traj_filename)+"\".\n", FILE_ERROR); return COLVARS_ERROR; } } break; } } } return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } std::ostream & colvarmodule::write_restart(std::ostream &os) { os.setf(std::ios::scientific, std::ios::floatfield); os << "configuration {\n" << " step " << std::setw(it_width) << it << "\n" << " dt " << dt() << "\n" << " version " << std::string(COLVARS_VERSION) << "\n" << "}\n\n"; cvm::increase_depth(); for (std::vector::iterator cvi = colvars.begin(); cvi != colvars.end(); cvi++) { (*cvi)->write_restart(os); } for (std::vector::iterator bi = biases.begin(); bi != biases.end(); bi++) { (*bi)->write_restart(os); } cvm::decrease_depth(); return os; } int colvarmodule::open_traj_file(std::string const &file_name) { if (cv_traj_os.is_open()) { return COLVARS_OK; } // (re)open trajectory file if (cv_traj_append) { cvm::log("Appending to colvar trajectory file \""+file_name+ "\".\n"); cv_traj_os.open(file_name.c_str(), std::ios::app); } else { cvm::log("Writing to colvar trajectory file \""+file_name+ "\".\n"); proxy->backup_file(file_name.c_str()); cv_traj_os.open(file_name.c_str()); } if (!cv_traj_os.is_open()) { cvm::error("Error: cannot write to file \""+file_name+"\".\n", FILE_ERROR); } return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } int colvarmodule::close_traj_file() { if (cv_traj_os.is_open()) { cv_traj_os.close(); } return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } std::ostream & colvarmodule::write_traj_label(std::ostream &os) { if (!os.good()) { cvm::error("Cannot write to trajectory file."); return os; } os.setf(std::ios::scientific, std::ios::floatfield); os << "# " << cvm::wrap_string("step", cvm::it_width-2) << " "; cvm::increase_depth(); for (std::vector::iterator cvi = colvars.begin(); cvi != colvars.end(); cvi++) { (*cvi)->write_traj_label(os); } for (std::vector::iterator bi = biases.begin(); bi != biases.end(); bi++) { (*bi)->write_traj_label(os); } os << "\n"; if (cvm::debug()) { os.flush(); } cvm::decrease_depth(); return os; } std::ostream & colvarmodule::write_traj(std::ostream &os) { os.setf(std::ios::scientific, std::ios::floatfield); os << std::setw(cvm::it_width) << it << " "; cvm::increase_depth(); for (std::vector::iterator cvi = colvars.begin(); cvi != colvars.end(); cvi++) { (*cvi)->write_traj(os); } for (std::vector::iterator bi = biases.begin(); bi != biases.end(); bi++) { (*bi)->write_traj(os); } os << "\n"; if (cvm::debug()) { os.flush(); } cvm::decrease_depth(); return os; } void cvm::log(std::string const &message) { size_t const d = depth(); if (d > 0) proxy->log((std::string(2*d, ' '))+message); else proxy->log(message); } void cvm::increase_depth() { (depth())++; } void cvm::decrease_depth() { if (depth() > 0) { (depth())--; } } size_t & cvm::depth() { // NOTE: do not call log() or error() here, to avoid recursion size_t const nt = proxy->smp_num_threads(); if (proxy->smp_enabled() == COLVARS_OK) { if (depth_v.size() != nt) { // update array of depths proxy->smp_lock(); if (depth_v.size() > 0) { depth_s = depth_v[0]; } depth_v.clear(); depth_v.assign(nt, depth_s); proxy->smp_unlock(); } return depth_v[proxy->smp_thread_id()]; } return depth_s; } void colvarmodule::set_error_bits(int code) { if (code < 0) { cvm::fatal_error("Error: set_error_bits() received negative error code.\n"); return; } proxy->smp_lock(); errorCode |= code | COLVARS_ERROR; proxy->smp_unlock(); } bool colvarmodule::get_error_bit(int code) { return bool(errorCode & code); } void colvarmodule::clear_error() { proxy->smp_lock(); errorCode = COLVARS_OK; proxy->smp_unlock(); } void cvm::error(std::string const &message, int code) { set_error_bits(code); proxy->error(message); } void cvm::fatal_error(std::string const &message) { // TODO once all non-fatal errors have been set to be handled by error(), // set DELETE_COLVARS here for VMD to handle it set_error_bits(FATAL_ERROR); proxy->fatal_error(message); } void cvm::exit(std::string const &message) { proxy->exit(message); } int cvm::read_index_file(char const *filename) { std::ifstream is(filename, std::ios::binary); if (!is.good()) { cvm::error("Error: in opening index file \""+ std::string(filename)+"\".\n", FILE_ERROR); } while (is.good()) { char open, close; std::string group_name; if ( (is >> open) && (open == '[') && (is >> group_name) && (is >> close) && (close == ']') ) { for (std::list::iterator names_i = index_group_names.begin(); names_i != index_group_names.end(); names_i++) { if (*names_i == group_name) { cvm::error("Error: the group name \""+group_name+ "\" appears in multiple index files.\n", FILE_ERROR); } } cvm::index_group_names.push_back(group_name); cvm::index_groups.push_back(std::vector ()); } else { cvm::error("Error: in parsing index file \""+ std::string(filename)+"\".\n", INPUT_ERROR); } int atom_number = 1; size_t pos = is.tellg(); while ( (is >> atom_number) && (atom_number > 0) ) { (cvm::index_groups.back()).push_back(atom_number); pos = is.tellg(); } is.clear(); is.seekg(pos, std::ios::beg); std::string delim; if ( (is >> delim) && (delim == "[") ) { // new group is.clear(); is.seekg(pos, std::ios::beg); } else { break; } } cvm::log("The following index groups were read from the index file \""+ std::string(filename)+"\":\n"); std::list::iterator names_i = index_group_names.begin(); std::list >::iterator lists_i = index_groups.begin(); for ( ; names_i != index_group_names.end() ; names_i++, lists_i++) { cvm::log(" "+(*names_i)+" ("+cvm::to_str(lists_i->size())+" atoms).\n"); } return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } int cvm::load_atoms(char const *file_name, cvm::atom_group &atoms, std::string const &pdb_field, double const pdb_field_value) { return proxy->load_atoms(file_name, atoms, pdb_field, pdb_field_value); } int cvm::load_coords(char const *file_name, std::vector &pos, const std::vector &indices, std::string const &pdb_field, double const pdb_field_value) { // Differentiate between PDB and XYZ files // for XYZ files, use CVM internal parser // otherwise call proxy function for PDB std::string const ext(strlen(file_name) > 4 ? (file_name + (strlen(file_name) - 4)) : file_name); if (colvarparse::to_lower_cppstr(ext) == std::string(".xyz")) { if ( pdb_field.size() > 0 ) { cvm::error("Error: PDB column may not be specified for XYZ coordinate file.\n", INPUT_ERROR); return COLVARS_ERROR; } return cvm::load_coords_xyz(file_name, pos, indices); } else { return proxy->load_coords(file_name, pos, indices, pdb_field, pdb_field_value); } } int cvm::load_coords_xyz(char const *filename, std::vector &pos, const std::vector &indices) { std::ifstream xyz_is(filename); unsigned int natoms; char symbol[256]; std::string line; if ( ! (xyz_is >> natoms) ) { cvm::error("Error: cannot parse XYZ file " + std::string(filename) + ".\n", INPUT_ERROR); } // skip comment line std::getline(xyz_is, line); std::getline(xyz_is, line); xyz_is.width(255); std::vector::iterator pos_i = pos.begin(); if (pos.size() != natoms) { // Use specified indices int next = 0; // indices are zero-based std::vector::const_iterator index = indices.begin(); for ( ; pos_i != pos.end() ; pos_i++, index++) { while ( next < *index ) { std::getline(xyz_is, line); next++; } xyz_is >> symbol; xyz_is >> (*pos_i)[0] >> (*pos_i)[1] >> (*pos_i)[2]; } } else { // Use all positions for ( ; pos_i != pos.end() ; pos_i++) { xyz_is >> symbol; xyz_is >> (*pos_i)[0] >> (*pos_i)[1] >> (*pos_i)[2]; } } return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } // static pointers std::vector colvarmodule::colvars; std::vector colvarmodule::biases; size_t colvarmodule::n_abf_biases = 0; size_t colvarmodule::n_rest_biases = 0; size_t colvarmodule::n_histo_biases = 0; size_t colvarmodule::n_meta_biases = 0; colvarproxy *colvarmodule::proxy = NULL; // static runtime data cvm::real colvarmodule::debug_gradients_step_size = 1.0e-07; int colvarmodule::errorCode = 0; long colvarmodule::it = 0; long colvarmodule::it_restart = 0; size_t colvarmodule::restart_out_freq = 0; size_t colvarmodule::cv_traj_freq = 0; size_t colvarmodule::depth_s = 0; std::vector colvarmodule::depth_v(0); bool colvarmodule::b_analysis = false; std::list colvarmodule::index_group_names; std::list > colvarmodule::index_groups; bool colvarmodule::use_scripted_forces = false; bool colvarmodule::scripting_after_biases = true; // file name prefixes std::string colvarmodule::output_prefix = ""; std::string colvarmodule::restart_in_name = ""; // i/o constants size_t const colvarmodule::it_width = 12; size_t const colvarmodule::cv_prec = 14; size_t const colvarmodule::cv_width = 21; size_t const colvarmodule::en_prec = 14; size_t const colvarmodule::en_width = 21; -std::string const colvarmodule::line_marker = +const char * const colvarmodule::line_marker = (const char *) "----------------------------------------------------------------------\n"; diff --git a/lib/colvars/colvarmodule.h b/lib/colvars/colvarmodule.h index 454fb65b6..0b19d1f77 100644 --- a/lib/colvars/colvarmodule.h +++ b/lib/colvars/colvarmodule.h @@ -1,671 +1,671 @@ // -*- c++ -*- #ifndef COLVARMODULE_H #define COLVARMODULE_H #ifndef COLVARS_VERSION #define COLVARS_VERSION "2016-10-05" #endif #ifndef COLVARS_DEBUG #define COLVARS_DEBUG false #endif /*! \mainpage Main page */ /// \file colvarmodule.h /// \brief Collective variables main module /// /// This file declares the main class for defining and manipulating /// collective variables: there should be only one instance of this /// class, because several variables are made static (i.e. they are /// shared between all object instances) to be accessed from other /// objects. #define COLVARS_OK 0 #define COLVARS_ERROR 1 #define COLVARS_NOT_IMPLEMENTED (1<<1) #define INPUT_ERROR (1<<2) // out of bounds or inconsistent input #define BUG_ERROR (1<<3) // Inconsistent state indicating bug #define FILE_ERROR (1<<4) #define MEMORY_ERROR (1<<5) #define FATAL_ERROR (1<<6) // Should be set, or not, together with other bits #define DELETE_COLVARS (1<<7) // Instruct the caller to delete cvm #define COLVARS_NO_SUCH_FRAME (1<<8) // Cannot load the requested frame #include #include #include #include #include #include #include #include #include #ifdef NAMD_VERSION // use Lustre-friendly wrapper to POSIX write() #include "fstream_namd.h" #endif class colvarparse; class colvar; class colvarbias; class colvarproxy; class colvarscript; /// \brief Collective variables module (main class) /// /// Class to control the collective variables calculation. An object /// (usually one) of this class is spawned from the MD program, /// containing all i/o routines and general interface. /// /// At initialization, the colvarmodule object creates a proxy object /// to provide a transparent interface between the MD program and the /// child objects class colvarmodule { private: /// Impossible to initialize the main object without arguments colvarmodule(); public: friend class colvarproxy; // TODO colvarscript should be unaware of colvarmodule's internals friend class colvarscript; /// Defining an abstract real number allows to switch precision typedef double real; /// Residue identifier typedef int residue_id; class rvector; template class vector1d; template class matrix2d; class quaternion; class rotation; /// \brief Atom position (different type name from rvector, to make /// possible future PBC-transparent implementations) typedef rvector atom_pos; /// \brief 3x3 matrix of real numbers class rmatrix; // allow these classes to access protected data class atom; class atom_group; friend class atom; friend class atom_group; typedef std::vector::iterator atom_iter; typedef std::vector::const_iterator atom_const_iter; /// Module-wide error state /// see constants at the top of this file protected: static int errorCode; public: static void set_error_bits(int code); static bool get_error_bit(int code); static inline int get_error() { return errorCode; } static void clear_error(); /// Current step number static long it; /// Starting step number for this run static long it_restart; /// Return the current step number from the beginning of this run static inline long step_relative() { return it - it_restart; } /// Return the current step number from the beginning of the whole /// calculation static inline long step_absolute() { return it; } /// If true, get it_restart from the state file; if set to false, /// the MD program is providing it bool it_restart_from_state_file; /// \brief Finite difference step size (if there is no dynamics, or /// if gradients need to be tested independently from the size of /// dt) static real debug_gradients_step_size; /// Prefix for all output files for this run static std::string output_prefix; /// input restart file name (determined from input_prefix) static std::string restart_in_name; /// Array of collective variables static std::vector colvars; /* TODO: implement named CVCs /// Array of named (reusable) collective variable components static std::vector cvcs; /// Named cvcs register themselves at initialization time inline void register_cvc(cvc *p) { cvcs.push_back(p); } */ /// Collective variables to be calculated on different threads; /// colvars with multple items (e.g. multiple active CVCs) are duplicated std::vector colvars_smp; /// Indexes of the items to calculate for each colvar std::vector colvars_smp_items; /// Array of collective variable biases static std::vector biases; /// \brief Number of ABF biases initialized (in normal conditions /// should be 1) static size_t n_abf_biases; /// \brief Number of metadynamics biases initialized (in normal /// conditions should be 1) static size_t n_meta_biases; /// \brief Number of restraint biases initialized (no limit on the /// number) static size_t n_rest_biases; /// \brief Number of histograms initialized (no limit on the /// number) static size_t n_histo_biases; /// \brief Whether debug output should be enabled (compile-time option) static inline bool debug() { return COLVARS_DEBUG; } /// \brief Constructor \param config_name Configuration file name /// \param restart_name (optional) Restart file name colvarmodule(colvarproxy *proxy); /// Destructor ~colvarmodule(); /// Actual function called by the destructor int reset(); /// Open a config file, load its contents, and pass it to config_string() int read_config_file(char const *config_file_name); /// \brief Parse a config string assuming it is a complete configuration /// (i.e. calling all parse functions) int read_config_string(std::string const &conf); /// \brief Parse a "clean" config string (no comments) int parse_config(std::string &conf); // Parse functions (setup internal data based on a string) /// Parse the few module's global parameters int parse_global_params(std::string const &conf); /// Parse and initialize collective variables int parse_colvars(std::string const &conf); /// Parse and initialize collective variable biases int parse_biases(std::string const &conf); /// Parse and initialize collective variable biases of a specific type template int parse_biases_type(std::string const &conf, char const *keyword, size_t &bias_count); /// Test error condition and keyword parsing /// on error, delete new bias bool check_new_bias(std::string &conf, char const *key); private: /// Useful wrapper to interrupt parsing if any error occurs int catch_input_errors(int result); public: // "Setup" functions (change internal data based on related data // from the proxy that may change during program execution) // No additional parsing is done within these functions /// (Re)initialize internal data (currently used by LAMMPS) /// Also calls setup() member functions of colvars and biases int setup(); /// (Re)initialize and (re)read the input state file calling read_restart() int setup_input(); /// (Re)initialize the output trajectory and state file (does not write it yet) int setup_output(); #ifdef NAMD_VERSION typedef ofstream_namd ofstream; #else typedef std::ofstream ofstream; #endif /// Read the input restart file std::istream & read_restart(std::istream &is); /// Write the output restart file std::ostream & write_restart(std::ostream &os); /// Open a trajectory file if requested (and leave it open) int open_traj_file(std::string const &file_name); /// Close it int close_traj_file(); /// Write in the trajectory file std::ostream & write_traj(std::ostream &os); /// Write explanatory labels in the trajectory file std::ostream & write_traj_label(std::ostream &os); /// Write all trajectory files int write_traj_files(); /// Write all restart files int write_restart_files(); /// Write all FINAL output files int write_output_files(); /// Backup a file before writing it static int backup_file(char const *filename); /// Look up a bias by name; returns NULL if not found static colvarbias * bias_by_name(std::string const &name); /// Look up a colvar by name; returns NULL if not found static colvar * colvar_by_name(std::string const &name); /// Load new configuration for the given bias - /// currently works for harmonic (force constant and/or centers) int change_configuration(std::string const &bias_name, std::string const &conf); /// Read a colvar value std::string read_colvar(std::string const &name); /// Calculate change in energy from using alt. config. for the given bias - /// currently works for harmonic (force constant and/or centers) real energy_difference(std::string const &bias_name, std::string const &conf); /// Give the total number of bins for a given bias. int bias_bin_num(std::string const &bias_name); /// Calculate the bin index for a given bias. int bias_current_bin(std::string const &bias_name); //// Give the count at a given bin index. int bias_bin_count(std::string const &bias_name, size_t bin_index); //// Share among replicas. int bias_share(std::string const &bias_name); /// Main worker function int calc(); /// Calculate collective variables int calc_colvars(); /// Calculate biases int calc_biases(); /// Integrate bias and restraint forces, send colvar forces to atoms int update_colvar_forces(); /// Perform analysis int analyze(); /// \brief Read a collective variable trajectory (post-processing /// only, not called at runtime) int read_traj(char const *traj_filename, long traj_read_begin, long traj_read_end); /// Quick conversion of an object to a string template static std::string to_str(T const &x, size_t const &width = 0, size_t const &prec = 0); /// Quick conversion of a vector of objects to a string template static std::string to_str(std::vector const &x, size_t const &width = 0, size_t const &prec = 0); /// Reduce the number of characters in a string static inline std::string wrap_string(std::string const &s, size_t const &nchars) { if (!s.size()) return std::string(nchars, ' '); else return ( (s.size() <= size_t(nchars)) ? (s+std::string(nchars-s.size(), ' ')) : (std::string(s, 0, nchars)) ); } /// Number of characters to represent a time step static size_t const it_width; /// Number of digits to represent a collective variables value(s) static size_t const cv_prec; /// Number of characters to represent a collective variables value(s) static size_t const cv_width; /// Number of digits to represent the collective variables energy static size_t const en_prec; /// Number of characters to represent the collective variables energy static size_t const en_width; /// Line separator in the log output - static std::string const line_marker; + static const char * const line_marker; // proxy functions /// \brief Value of the unit for atomic coordinates with respect to /// angstroms (used by some variables for hard-coded default values) static real unit_angstrom(); /// \brief Boltmann constant static real boltzmann(); /// \brief Temperature of the simulation (K) static real temperature(); /// \brief Time step of MD integrator (fs) static real dt(); /// Request calculation of total force from MD engine static void request_total_force(); /// Print a message to the main log static void log(std::string const &message); /// Print a message to the main log and exit with error code static void fatal_error(std::string const &message); /// Print a message to the main log and set global error code static void error(std::string const &message, int code = COLVARS_ERROR); /// Print a message to the main log and exit normally static void exit(std::string const &message); // Replica exchange commands. static bool replica_enabled(); static int replica_index(); static int replica_num(); static void replica_comm_barrier(); static int replica_comm_recv(char* msg_data, int buf_len, int src_rep); static int replica_comm_send(char* msg_data, int msg_len, int dest_rep); /// \brief Get the distance between two atomic positions with pbcs handled /// correctly static rvector position_distance(atom_pos const &pos1, atom_pos const &pos2); /// \brief Get the square distance between two positions (with /// periodic boundary conditions handled transparently) /// /// Note: in the case of periodic boundary conditions, this provides /// an analytical square distance (while taking the square of /// position_distance() would produce leads to a cusp) static real position_dist2(atom_pos const &pos1, atom_pos const &pos2); /// \brief Get the closest periodic image to a reference position /// \param pos The position to look for the closest periodic image /// \param ref_pos (optional) The reference position static void select_closest_image(atom_pos &pos, atom_pos const &ref_pos); /// \brief Perform select_closest_image() on a set of atomic positions /// /// After that, distance vectors can then be calculated directly, /// without using position_distance() static void select_closest_images(std::vector &pos, atom_pos const &ref_pos); /// \brief Names of groups from a Gromacs .ndx file to be read at startup static std::list index_group_names; /// \brief Groups from a Gromacs .ndx file read at startup static std::list > index_groups; /// \brief Read a Gromacs .ndx file static int read_index_file(char const *filename); /// \brief Create atoms from a file \param filename name of the file /// (usually a PDB) \param atoms array of the atoms to be allocated /// \param pdb_field (optiona) if "filename" is a PDB file, use this /// field to determine which are the atoms to be set static int load_atoms(char const *filename, atom_group &atoms, std::string const &pdb_field, double const pdb_field_value = 0.0); /// \brief Load the coordinates for a group of atoms from a file /// (PDB or XYZ) static int load_coords(char const *filename, std::vector &pos, const std::vector &indices, std::string const &pdb_field, double const pdb_field_value = 0.0); /// \brief Load the coordinates for a group of atoms from an /// XYZ file static int load_coords_xyz(char const *filename, std::vector &pos, const std::vector &indices); /// Frequency for collective variables trajectory output static size_t cv_traj_freq; /// \brief True if only analysis is performed and not a run static bool b_analysis; /// Frequency for saving output restarts static size_t restart_out_freq; /// Output restart file name std::string restart_out_name; /// Pseudo-random number with Gaussian distribution static real rand_gaussian(void); protected: /// Configuration file std::ifstream config_s; /// Configuration file parser object colvarparse *parse; /// Name of the trajectory file std::string cv_traj_name; /// Collective variables output trajectory file colvarmodule::ofstream cv_traj_os; /// Appending to the existing trajectory file? bool cv_traj_append; /// Output restart file colvarmodule::ofstream restart_out_os; protected: /// Counter for the current depth in the object hierarchy (useg e.g. in output) static size_t depth_s; /// Thread-specific depth static std::vector depth_v; public: /// Get the current object depth in the hierarchy static size_t & depth(); /// Increase the depth (number of indentations in the output) static void increase_depth(); /// Decrease the depth (number of indentations in the output) static void decrease_depth(); static inline bool scripted_forces() { return use_scripted_forces; } /// Use scripted colvars forces? static bool use_scripted_forces; /// Wait for all biases before calculating scripted forces? static bool scripting_after_biases; /// Calculate the energy and forces of scripted biases int calc_scripted_forces(); /// \brief Pointer to the proxy object, used to retrieve atomic data /// from the hosting program; it is static in order to be accessible /// from static functions in the colvarmodule class static colvarproxy *proxy; }; /// Shorthand for the frequently used type prefix typedef colvarmodule cvm; #include "colvartypes.h" std::ostream & operator << (std::ostream &os, cvm::rvector const &v); std::istream & operator >> (std::istream &is, cvm::rvector &v); template std::string cvm::to_str(T const &x, size_t const &width, size_t const &prec) { std::ostringstream os; if (width) os.width(width); if (prec) { os.setf(std::ios::scientific, std::ios::floatfield); os.precision(prec); } os << x; return os.str(); } template std::string cvm::to_str(std::vector const &x, size_t const &width, size_t const &prec) { if (!x.size()) return std::string(""); std::ostringstream os; if (prec) { os.setf(std::ios::scientific, std::ios::floatfield); } os << "{ "; if (width) os.width(width); if (prec) os.precision(prec); os << x[0]; for (size_t i = 1; i < x.size(); i++) { os << ", "; if (width) os.width(width); if (prec) os.precision(prec); os << x[i]; } os << " }"; return os.str(); } #include "colvarproxy.h" inline cvm::real cvm::unit_angstrom() { return proxy->unit_angstrom(); } inline cvm::real cvm::boltzmann() { return proxy->boltzmann(); } inline cvm::real cvm::temperature() { return proxy->temperature(); } inline cvm::real cvm::dt() { return proxy->dt(); } // Replica exchange commands inline bool cvm::replica_enabled() { return proxy->replica_enabled(); } inline int cvm::replica_index() { return proxy->replica_index(); } inline int cvm::replica_num() { return proxy->replica_num(); } inline void cvm::replica_comm_barrier() { return proxy->replica_comm_barrier(); } inline int cvm::replica_comm_recv(char* msg_data, int buf_len, int src_rep) { return proxy->replica_comm_recv(msg_data,buf_len,src_rep); } inline int cvm::replica_comm_send(char* msg_data, int msg_len, int dest_rep) { return proxy->replica_comm_send(msg_data,msg_len,dest_rep); } inline void cvm::request_total_force() { proxy->request_total_force(true); } inline void cvm::select_closest_image(atom_pos &pos, atom_pos const &ref_pos) { proxy->select_closest_image(pos, ref_pos); } inline void cvm::select_closest_images(std::vector &pos, atom_pos const &ref_pos) { proxy->select_closest_images(pos, ref_pos); } inline cvm::rvector cvm::position_distance(atom_pos const &pos1, atom_pos const &pos2) { return proxy->position_distance(pos1, pos2); } inline cvm::real cvm::position_dist2(cvm::atom_pos const &pos1, cvm::atom_pos const &pos2) { return proxy->position_dist2(pos1, pos2); } inline cvm::real cvm::rand_gaussian(void) { return proxy->rand_gaussian(); } #endif diff --git a/lib/quip/Makefile.lammps b/lib/quip/Makefile.lammps index 10c0fd6bd..19ff20b07 100644 --- a/lib/quip/Makefile.lammps +++ b/lib/quip/Makefile.lammps @@ -1,28 +1,30 @@ # Settings that the LAMMPS build will import when this package library is used # include ${QUIP_ROOT}/Makefiles/Makefile.${QUIP_ARCH} F95=$(shell egrep 'F95[ ]*=' ${QUIP_ROOT}/arch/Makefile.${QUIP_ARCH} | sed 's/.*F95[ ]*=[ ]*//') ifeq (${QUIP_ROOT},) $(error Environment variable QUIP_ROOT must be set.) endif ifeq (${QUIP_ARCH},) $(error Environment variable QUIP_ARCH must be set.) endif include ${QUIP_ROOT}/build/${QUIP_ARCH}/Makefile.inc +include ${QUIP_ROOT}/Makefile.rules quip_SYSLIB = -lquip +quip_SYSLIB += ${NETCDF_SYSLIBS} quip_SYSLIB += ${MATH_LINKOPTS} ifeq (${F95},gfortran) quip_SYSLIB += -lgfortran else ifeq (${F95},ifort) quip_SYSLIB += -lifcore -lifport else $(error fortran compiler >>${F95}<< not recognised. Edit lib/quip/Makefile.lammps to specify the fortran library your linker should link to) endif -quip_SYSPATH = -L${QUIP_ROOT}/build/${QUIP_ARCH} -L${QUIP_ROOT}/src/FoX-4.0.3/objs.${QUIP_ARCH}/lib +quip_SYSPATH = -L${QUIP_ROOT}/build/${QUIP_ARCH} diff --git a/src/GRANULAR/fix_wall_gran.cpp b/src/GRANULAR/fix_wall_gran.cpp index 4e927b257..8ba6a2402 100644 --- a/src/GRANULAR/fix_wall_gran.cpp +++ b/src/GRANULAR/fix_wall_gran.cpp @@ -1,851 +1,1150 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Contributing authors: Leo Silbert (SNL), Gary Grest (SNL) + Contributing authors: Leo Silbert (SNL), Gary Grest (SNL), + Dan Bolintineanu (SNL) ------------------------------------------------------------------------- */ #include #include #include #include "fix_wall_gran.h" #include "atom.h" #include "domain.h" #include "update.h" #include "force.h" #include "pair.h" #include "modify.h" #include "respa.h" #include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; using namespace FixConst; using namespace MathConst; -enum{XPLANE=0,YPLANE=1,ZPLANE=2,ZCYLINDER}; // XYZ PLANE need to be 0,1,2 -enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY}; +// XYZ PLANE need to be 0,1,2 + +enum{XPLANE=0,YPLANE=1,ZPLANE=2,ZCYLINDER,REGION}; +enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY,BONDED_HISTORY}; +enum{NONE,CONSTANT,EQUAL}; #define BIG 1.0e20 /* ---------------------------------------------------------------------- */ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 11) error->all(FLERR,"Illegal fix wall/gran command"); + if (narg < 4) error->all(FLERR,"Illegal fix wall/gran command"); if (!atom->sphere_flag) error->all(FLERR,"Fix wall/gran requires atom style sphere"); restart_peratom = 1; create_attribute = 1; // set interaction style + // disable bonded/history option for now if (strcmp(arg[3],"hooke") == 0) pairstyle = HOOKE; else if (strcmp(arg[3],"hooke/history") == 0) pairstyle = HOOKE_HISTORY; else if (strcmp(arg[3],"hertz/history") == 0) pairstyle = HERTZ_HISTORY; + //else if (strcmp(arg[3],"bonded/history") == 0) pairstyle = BONDED_HISTORY; else error->all(FLERR,"Invalid fix wall/gran interaction style"); history = 1; if (pairstyle == HOOKE) history = 0; - // particle/wall coefficients + // wall/particle coefficients + + int iarg; + + if (pairstyle != BONDED_HISTORY) { + if (narg < 11) error->all(FLERR,"Illegal fix wall/gran command"); - kn = force->numeric(FLERR,arg[4]); - if (strcmp(arg[5],"NULL") == 0) kt = kn * 2.0/7.0; - else kt = force->numeric(FLERR,arg[5]); + kn = force->numeric(FLERR,arg[4]); + if (strcmp(arg[5],"NULL") == 0) kt = kn * 2.0/7.0; + else kt = force->numeric(FLERR,arg[5]); - gamman = force->numeric(FLERR,arg[6]); - if (strcmp(arg[7],"NULL") == 0) gammat = 0.5 * gamman; - else gammat = force->numeric(FLERR,arg[7]); + gamman = force->numeric(FLERR,arg[6]); + if (strcmp(arg[7],"NULL") == 0) gammat = 0.5 * gamman; + else gammat = force->numeric(FLERR,arg[7]); - xmu = force->numeric(FLERR,arg[8]); - int dampflag = force->inumeric(FLERR,arg[9]); - if (dampflag == 0) gammat = 0.0; + xmu = force->numeric(FLERR,arg[8]); + int dampflag = force->inumeric(FLERR,arg[9]); + if (dampflag == 0) gammat = 0.0; - if (kn < 0.0 || kt < 0.0 || gamman < 0.0 || gammat < 0.0 || - xmu < 0.0 || xmu > 10000.0 || dampflag < 0 || dampflag > 1) - error->all(FLERR,"Illegal fix wall/gran command"); + if (kn < 0.0 || kt < 0.0 || gamman < 0.0 || gammat < 0.0 || + xmu < 0.0 || xmu > 10000.0 || dampflag < 0 || dampflag > 1) + error->all(FLERR,"Illegal fix wall/gran command"); - // convert Kn and Kt from pressure units to force/distance^2 if Hertzian + // convert Kn and Kt from pressure units to force/distance^2 if Hertzian + + if (pairstyle == HERTZ_HISTORY) { + kn /= force->nktv2p; + kt /= force->nktv2p; + } - if (pairstyle == HERTZ_HISTORY) { - kn /= force->nktv2p; - kt /= force->nktv2p; + iarg = 10; + } + + else { + if (narg < 10) error->all(FLERR,"Illegal fix wall/gran command"); + + E = force->numeric(FLERR,arg[4]); + G = force->numeric(FLERR,arg[5]); + SurfEnergy = force->numeric(FLERR,arg[6]); + // Note: this doesn't get used, check w/ Jeremy? + gamman = force->numeric(FLERR,arg[7]); + + xmu = force->numeric(FLERR,arg[8]); + // pois = E/(2.0*G) - 1.0; + // kn = 2.0*E/(3.0*(1.0+pois)*(1.0-pois)); + // gammat=0.5*gamman; + + iarg = 9; } // wallstyle args - int iarg = 10; + idregion = NULL; + if (strcmp(arg[iarg],"xplane") == 0) { if (narg < iarg+3) error->all(FLERR,"Illegal fix wall/gran command"); wallstyle = XPLANE; if (strcmp(arg[iarg+1],"NULL") == 0) lo = -BIG; else lo = force->numeric(FLERR,arg[iarg+1]); if (strcmp(arg[iarg+2],"NULL") == 0) hi = BIG; else hi = force->numeric(FLERR,arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg],"yplane") == 0) { if (narg < iarg+3) error->all(FLERR,"Illegal fix wall/gran command"); wallstyle = YPLANE; if (strcmp(arg[iarg+1],"NULL") == 0) lo = -BIG; else lo = force->numeric(FLERR,arg[iarg+1]); if (strcmp(arg[iarg+2],"NULL") == 0) hi = BIG; else hi = force->numeric(FLERR,arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg],"zplane") == 0) { if (narg < iarg+3) error->all(FLERR,"Illegal fix wall/gran command"); wallstyle = ZPLANE; if (strcmp(arg[iarg+1],"NULL") == 0) lo = -BIG; else lo = force->numeric(FLERR,arg[iarg+1]); if (strcmp(arg[iarg+2],"NULL") == 0) hi = BIG; else hi = force->numeric(FLERR,arg[iarg+2]); iarg += 3; } else if (strcmp(arg[iarg],"zcylinder") == 0) { if (narg < iarg+2) error->all(FLERR,"Illegal fix wall/gran command"); wallstyle = ZCYLINDER; lo = hi = 0.0; - cylradius = force->numeric(FLERR,arg[iarg+1]); + cylradius = force->numeric(FLERR,arg[iarg+3]); + iarg += 2; + } else if (strcmp(arg[iarg],"region") == 0) { + if (narg < iarg+2) error->all(FLERR,"Illegal fix wall/gran command"); + wallstyle = REGION; + int n = strlen(arg[iarg+1]) + 1; + idregion = new char[n]; + strcpy(idregion,arg[iarg+1]); iarg += 2; } - // check for trailing keyword/values + // optional args wiggle = 0; wshear = 0; while (iarg < narg) { if (strcmp(arg[iarg],"wiggle") == 0) { if (iarg+4 > narg) error->all(FLERR,"Illegal fix wall/gran command"); if (strcmp(arg[iarg+1],"x") == 0) axis = 0; else if (strcmp(arg[iarg+1],"y") == 0) axis = 1; else if (strcmp(arg[iarg+1],"z") == 0) axis = 2; else error->all(FLERR,"Illegal fix wall/gran command"); amplitude = force->numeric(FLERR,arg[iarg+2]); period = force->numeric(FLERR,arg[iarg+3]); wiggle = 1; iarg += 4; } else if (strcmp(arg[iarg],"shear") == 0) { if (iarg+3 > narg) error->all(FLERR,"Illegal fix wall/gran command"); if (strcmp(arg[iarg+1],"x") == 0) axis = 0; else if (strcmp(arg[iarg+1],"y") == 0) axis = 1; else if (strcmp(arg[iarg+1],"z") == 0) axis = 2; else error->all(FLERR,"Illegal fix wall/gran command"); vshear = force->numeric(FLERR,arg[iarg+2]); wshear = 1; iarg += 3; } else error->all(FLERR,"Illegal fix wall/gran command"); } if (wallstyle == XPLANE && domain->xperiodic) error->all(FLERR,"Cannot use wall in periodic dimension"); if (wallstyle == YPLANE && domain->yperiodic) error->all(FLERR,"Cannot use wall in periodic dimension"); if (wallstyle == ZPLANE && domain->zperiodic) error->all(FLERR,"Cannot use wall in periodic dimension"); if (wallstyle == ZCYLINDER && (domain->xperiodic || domain->yperiodic)) error->all(FLERR,"Cannot use wall in periodic dimension"); if (wiggle && wshear) error->all(FLERR,"Cannot wiggle and shear fix wall/gran"); if (wiggle && wallstyle == ZCYLINDER && axis != 2) error->all(FLERR,"Invalid wiggle direction for fix wall/gran"); if (wshear && wallstyle == XPLANE && axis == 0) error->all(FLERR,"Invalid shear direction for fix wall/gran"); if (wshear && wallstyle == YPLANE && axis == 1) error->all(FLERR,"Invalid shear direction for fix wall/gran"); if (wshear && wallstyle == ZPLANE && axis == 2) error->all(FLERR,"Invalid shear direction for fix wall/gran"); + if ((wiggle || wshear) && wallstyle == REGION) + error->all(FLERR,"Cannot wiggle or shear with fix wall/gran/region"); // setup oscillations if (wiggle) omega = 2.0*MY_PI / period; // perform initial allocation of atom-based arrays // register with Atom class - shear = NULL; + if (pairstyle == BONDED_HISTORY) sheardim = 7; + else sheardim = 3; + + shearone = NULL; grow_arrays(atom->nmax); atom->add_callback(0); atom->add_callback(1); nmax = 0; mass_rigid = NULL; - // initialize as if particle is not touching wall + // initialize shear history as if particle is not touching region + // shearone will be NULL for wallstyle = REGION - if (history) { + if (history && shearone) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) - shear[i][0] = shear[i][1] = shear[i][2] = 0.0; + for (int j = 0; j < sheardim; j++) + shearone[i][j] = 0.0; } time_origin = update->ntimestep; } /* ---------------------------------------------------------------------- */ FixWallGran::~FixWallGran() { // unregister callbacks to this fix from Atom class atom->delete_callback(id,0); atom->delete_callback(id,1); - // delete locally stored arrays + // delete local storage - memory->destroy(shear); + delete [] idregion; + memory->destroy(shearone); memory->destroy(mass_rigid); } /* ---------------------------------------------------------------------- */ int FixWallGran::setmask() { int mask = 0; mask |= POST_FORCE; mask |= POST_FORCE_RESPA; return mask; } /* ---------------------------------------------------------------------- */ void FixWallGran::init() { int i; dt = update->dt; if (strstr(update->integrate_style,"respa")) nlevels_respa = ((Respa *) update->integrate)->nlevels; // check for FixRigid so can extract rigid body masses fix_rigid = NULL; for (i = 0; i < modify->nfix; i++) if (modify->fix[i]->rigid_flag) break; if (i < modify->nfix) fix_rigid = modify->fix[i]; } /* ---------------------------------------------------------------------- */ void FixWallGran::setup(int vflag) { if (strstr(update->integrate_style,"verlet")) post_force(vflag); else { ((Respa *) update->integrate)->copy_flevel_f(nlevels_respa-1); post_force_respa(vflag,nlevels_respa-1,0); ((Respa *) update->integrate)->copy_f_flevel(nlevels_respa-1); } } /* ---------------------------------------------------------------------- */ void FixWallGran::post_force(int vflag) { - int i; - double dx,dy,dz,del1,del2,delxy,delr,rsq,meff; + int i,j; + double dx,dy,dz,del1,del2,delxy,delr,rsq,rwall,meff; double vwall[3]; // do not update shear history during setup shearupdate = 1; if (update->setupflag) shearupdate = 0; // if just reneighbored: // update rigid body masses for owned atoms if using FixRigid // body[i] = which body atom I is in, -1 if none // mass_body = mass of each rigid body if (neighbor->ago == 0 && fix_rigid) { int tmp; int *body = (int *) fix_rigid->extract("body",tmp); double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); if (atom->nmax > nmax) { memory->destroy(mass_rigid); nmax = atom->nmax; memory->create(mass_rigid,nmax,"wall/gran:mass_rigid"); } int nlocal = atom->nlocal; for (i = 0; i < nlocal; i++) { if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; else mass_rigid[i] = 0.0; } } // set position of wall to initial settings and velocity to 0.0 // if wiggle or shear, set wall position and velocity accordingly double wlo = lo; double whi = hi; vwall[0] = vwall[1] = vwall[2] = 0.0; if (wiggle) { double arg = omega * (update->ntimestep - time_origin) * dt; if (wallstyle == axis) { wlo = lo + amplitude - amplitude*cos(arg); whi = hi + amplitude - amplitude*cos(arg); } vwall[axis] = amplitude*omega*sin(arg); } else if (wshear) vwall[axis] = vshear; // loop over all my atoms // rsq = distance from wall // dx,dy,dz = signed distance from wall // for rotating cylinder, reset vwall based on particle position // skip atom if not close enough to wall // if wall was set to NULL, it's skipped since lo/hi are infinity // compute force and torque on atom if close enough to wall // via wall potential matched to pair potential // set shear if pair potential stores history double **x = atom->x; double **v = atom->v; double **f = atom->f; double **omega = atom->omega; double **torque = atom->torque; double *radius = atom->radius; double *rmass = atom->rmass; int *mask = atom->mask; int nlocal = atom->nlocal; + rwall = 0.0; + for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { dx = dy = dz = 0.0; if (wallstyle == XPLANE) { del1 = x[i][0] - wlo; del2 = whi - x[i][0]; if (del1 < del2) dx = del1; else dx = -del2; } else if (wallstyle == YPLANE) { del1 = x[i][1] - wlo; del2 = whi - x[i][1]; if (del1 < del2) dy = del1; else dy = -del2; } else if (wallstyle == ZPLANE) { del1 = x[i][2] - wlo; del2 = whi - x[i][2]; if (del1 < del2) dz = del1; else dz = -del2; } else if (wallstyle == ZCYLINDER) { delxy = sqrt(x[i][0]*x[i][0] + x[i][1]*x[i][1]); delr = cylradius - delxy; - if (delr > radius[i]) dz = cylradius; - else { + if (delr > radius[i]) { + dz = cylradius; + rwall = 0.0; + } else { dx = -delr/delxy * x[i][0]; dy = -delr/delxy * x[i][1]; + // rwall = -2r_c if inside cylinder, 2r_c outside + rwall = (delxy < cylradius) ? -2*cylradius : 2*cylradius; if (wshear && axis != 2) { - vwall[0] = vshear * x[i][1]/delxy; - vwall[1] = -vshear * x[i][0]/delxy; + vwall[0] += vshear * x[i][1]/delxy; + vwall[1] += -vshear * x[i][0]/delxy; vwall[2] = 0.0; } } } rsq = dx*dx + dy*dy + dz*dz; if (rsq > radius[i]*radius[i]) { - if (pairstyle != HOOKE) { - shear[i][0] = 0.0; - shear[i][1] = 0.0; - shear[i][2] = 0.0; - } + if (history) + for (j = 0; j < sheardim; j++) + shearone[i][j] = 0.0; + } else { // meff = effective mass of sphere // if I is part of rigid body, use body mass meff = rmass[i]; if (fix_rigid && mass_rigid[i] > 0.0) meff = mass_rigid[i]; - // inovke sphere/wall interaction + // invoke sphere/wall interaction if (pairstyle == HOOKE) - hooke(rsq,dx,dy,dz,vwall,v[i],f[i],omega[i],torque[i], - radius[i],meff); + hooke(rsq,dx,dy,dz,vwall,v[i],f[i], + omega[i],torque[i],radius[i],meff); else if (pairstyle == HOOKE_HISTORY) - hooke_history(rsq,dx,dy,dz,vwall,v[i],f[i],omega[i],torque[i], - radius[i],meff,shear[i]); + hooke_history(rsq,dx,dy,dz,vwall,v[i],f[i], + omega[i],torque[i],radius[i],meff,shearone[i]); else if (pairstyle == HERTZ_HISTORY) - hertz_history(rsq,dx,dy,dz,vwall,v[i],f[i],omega[i],torque[i], - radius[i],meff,shear[i]); + hertz_history(rsq,dx,dy,dz,vwall,rwall,v[i],f[i], + omega[i],torque[i],radius[i],meff,shearone[i]); + else if (pairstyle == BONDED_HISTORY) + bonded_history(rsq,dx,dy,dz,vwall,rwall,v[i],f[i], + omega[i],torque[i],radius[i],meff,shearone[i]); } } } } /* ---------------------------------------------------------------------- */ void FixWallGran::post_force_respa(int vflag, int ilevel, int iloop) { if (ilevel == nlevels_respa-1) post_force(vflag); } /* ---------------------------------------------------------------------- */ void FixWallGran::hooke(double rsq, double dx, double dy, double dz, double *vwall, double *v, double *f, double *omega, double *torque, double radius, double meff) { double r,vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double wr1,wr2,wr3,damp,ccel,vtr1,vtr2,vtr3,vrel; double fn,fs,ft,fs1,fs2,fs3,fx,fy,fz,tor1,tor2,tor3,rinv,rsqinv; r = sqrt(rsq); rinv = 1.0/r; rsqinv = 1.0/rsq; // relative translational velocity vr1 = v[0] - vwall[0]; vr2 = v[1] - vwall[1]; vr3 = v[2] - vwall[2]; // normal component vnnr = vr1*dx + vr2*dy + vr3*dz; vn1 = dx*vnnr * rsqinv; vn2 = dy*vnnr * rsqinv; vn3 = dz*vnnr * rsqinv; // tangential component vt1 = vr1 - vn1; vt2 = vr2 - vn2; vt3 = vr3 - vn3; // relative rotational velocity wr1 = radius*omega[0] * rinv; wr2 = radius*omega[1] * rinv; wr3 = radius*omega[2] * rinv; // normal forces = Hookian contact + normal velocity damping damp = meff*gamman*vnnr*rsqinv; ccel = kn*(radius-r)*rinv - damp; // relative velocities vtr1 = vt1 - (dz*wr2-dy*wr3); vtr2 = vt2 - (dx*wr3-dz*wr1); vtr3 = vt3 - (dy*wr1-dx*wr2); vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; vrel = sqrt(vrel); // force normalization fn = xmu * fabs(ccel*r); fs = meff*gammat*vrel; if (vrel != 0.0) ft = MIN(fn,fs) / vrel; else ft = 0.0; // tangential force due to tangential velocity damping fs1 = -ft*vtr1; fs2 = -ft*vtr2; fs3 = -ft*vtr3; // forces & torques fx = dx*ccel + fs1; fy = dy*ccel + fs2; fz = dz*ccel + fs3; f[0] += fx; f[1] += fy; f[2] += fz; tor1 = rinv * (dy*fs3 - dz*fs2); tor2 = rinv * (dz*fs1 - dx*fs3); tor3 = rinv * (dx*fs2 - dy*fs1); torque[0] -= radius*tor1; torque[1] -= radius*tor2; torque[2] -= radius*tor3; } /* ---------------------------------------------------------------------- */ void FixWallGran::hooke_history(double rsq, double dx, double dy, double dz, double *vwall, double *v, double *f, double *omega, double *torque, double radius, double meff, double *shear) { double r,vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double wr1,wr2,wr3,damp,ccel,vtr1,vtr2,vtr3,vrel; double fn,fs,fs1,fs2,fs3,fx,fy,fz,tor1,tor2,tor3; double shrmag,rsht,rinv,rsqinv; r = sqrt(rsq); rinv = 1.0/r; rsqinv = 1.0/rsq; // relative translational velocity vr1 = v[0] - vwall[0]; vr2 = v[1] - vwall[1]; vr3 = v[2] - vwall[2]; // normal component vnnr = vr1*dx + vr2*dy + vr3*dz; vn1 = dx*vnnr * rsqinv; vn2 = dy*vnnr * rsqinv; vn3 = dz*vnnr * rsqinv; // tangential component vt1 = vr1 - vn1; vt2 = vr2 - vn2; vt3 = vr3 - vn3; // relative rotational velocity wr1 = radius*omega[0] * rinv; wr2 = radius*omega[1] * rinv; wr3 = radius*omega[2] * rinv; // normal forces = Hookian contact + normal velocity damping damp = meff*gamman*vnnr*rsqinv; ccel = kn*(radius-r)*rinv - damp; // relative velocities vtr1 = vt1 - (dz*wr2-dy*wr3); vtr2 = vt2 - (dx*wr3-dz*wr1); vtr3 = vt3 - (dy*wr1-dx*wr2); vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; vrel = sqrt(vrel); // shear history effects if (shearupdate) { shear[0] += vtr1*dt; shear[1] += vtr2*dt; shear[2] += vtr3*dt; } shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + shear[2]*shear[2]); // rotate shear displacements rsht = shear[0]*dx + shear[1]*dy + shear[2]*dz; rsht = rsht*rsqinv; if (shearupdate) { shear[0] -= rsht*dx; shear[1] -= rsht*dy; shear[2] -= rsht*dz; } // tangential forces = shear + tangential velocity damping fs1 = - (kt*shear[0] + meff*gammat*vtr1); fs2 = - (kt*shear[1] + meff*gammat*vtr2); fs3 = - (kt*shear[2] + meff*gammat*vtr3); // rescale frictional displacements and forces if needed fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); fn = xmu * fabs(ccel*r); if (fs > fn) { if (shrmag != 0.0) { shear[0] = (fn/fs) * (shear[0] + meff*gammat*vtr1/kt) - meff*gammat*vtr1/kt; shear[1] = (fn/fs) * (shear[1] + meff*gammat*vtr2/kt) - meff*gammat*vtr2/kt; shear[2] = (fn/fs) * (shear[2] + meff*gammat*vtr3/kt) - meff*gammat*vtr3/kt; fs1 *= fn/fs ; fs2 *= fn/fs; fs3 *= fn/fs; } else fs1 = fs2 = fs3 = 0.0; } // forces & torques fx = dx*ccel + fs1; fy = dy*ccel + fs2; fz = dz*ccel + fs3; f[0] += fx; f[1] += fy; f[2] += fz; tor1 = rinv * (dy*fs3 - dz*fs2); tor2 = rinv * (dz*fs1 - dx*fs3); tor3 = rinv * (dx*fs2 - dy*fs1); torque[0] -= radius*tor1; torque[1] -= radius*tor2; torque[2] -= radius*tor3; } /* ---------------------------------------------------------------------- */ void FixWallGran::hertz_history(double rsq, double dx, double dy, double dz, - double *vwall, double *v, + double *vwall, double rwall, double *v, double *f, double *omega, double *torque, double radius, double meff, double *shear) { double r,vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double wr1,wr2,wr3,damp,ccel,vtr1,vtr2,vtr3,vrel; double fn,fs,fs1,fs2,fs3,fx,fy,fz,tor1,tor2,tor3; double shrmag,rsht,polyhertz,rinv,rsqinv; r = sqrt(rsq); rinv = 1.0/r; rsqinv = 1.0/rsq; // relative translational velocity vr1 = v[0] - vwall[0]; vr2 = v[1] - vwall[1]; vr3 = v[2] - vwall[2]; // normal component vnnr = vr1*dx + vr2*dy + vr3*dz; vn1 = dx*vnnr / rsq; vn2 = dy*vnnr / rsq; vn3 = dz*vnnr / rsq; // tangential component vt1 = vr1 - vn1; vt2 = vr2 - vn2; vt3 = vr3 - vn3; // relative rotational velocity wr1 = radius*omega[0] * rinv; wr2 = radius*omega[1] * rinv; wr3 = radius*omega[2] * rinv; // normal forces = Hertzian contact + normal velocity damping + // rwall = 0 is flat wall case + // rwall positive or negative is curved wall + // will break (as it should) if rwall is negative and + // its absolute value < radius of particle damp = meff*gamman*vnnr*rsqinv; ccel = kn*(radius-r)*rinv - damp; - polyhertz = sqrt((radius-r)*radius); + if (rwall == 0.0) polyhertz = sqrt((radius-r)*radius); + else polyhertz = sqrt((radius-r)*radius*rwall/(rwall+radius)); ccel *= polyhertz; // relative velocities vtr1 = vt1 - (dz*wr2-dy*wr3); vtr2 = vt2 - (dx*wr3-dz*wr1); vtr3 = vt3 - (dy*wr1-dx*wr2); vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; vrel = sqrt(vrel); // shear history effects if (shearupdate) { shear[0] += vtr1*dt; shear[1] += vtr2*dt; shear[2] += vtr3*dt; } shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + shear[2]*shear[2]); // rotate shear displacements rsht = shear[0]*dx + shear[1]*dy + shear[2]*dz; rsht = rsht*rsqinv; if (shearupdate) { shear[0] -= rsht*dx; shear[1] -= rsht*dy; shear[2] -= rsht*dz; } // tangential forces = shear + tangential velocity damping fs1 = -polyhertz * (kt*shear[0] + meff*gammat*vtr1); fs2 = -polyhertz * (kt*shear[1] + meff*gammat*vtr2); fs3 = -polyhertz * (kt*shear[2] + meff*gammat*vtr3); // rescale frictional displacements and forces if needed fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); fn = xmu * fabs(ccel*r); if (fs > fn) { if (shrmag != 0.0) { shear[0] = (fn/fs) * (shear[0] + meff*gammat*vtr1/kt) - meff*gammat*vtr1/kt; shear[1] = (fn/fs) * (shear[1] + meff*gammat*vtr2/kt) - meff*gammat*vtr2/kt; shear[2] = (fn/fs) * (shear[2] + meff*gammat*vtr3/kt) - meff*gammat*vtr3/kt; fs1 *= fn/fs ; fs2 *= fn/fs; fs3 *= fn/fs; } else fs1 = fs2 = fs3 = 0.0; } // forces & torques fx = dx*ccel + fs1; fy = dy*ccel + fs2; fz = dz*ccel + fs3; f[0] += fx; f[1] += fy; f[2] += fz; tor1 = rinv * (dy*fs3 - dz*fs2); tor2 = rinv * (dz*fs1 - dx*fs3); tor3 = rinv * (dx*fs2 - dy*fs1); torque[0] -= radius*tor1; torque[1] -= radius*tor2; torque[2] -= radius*tor3; } + +/* ---------------------------------------------------------------------- */ + +void FixWallGran::bonded_history(double rsq, double dx, double dy, double dz, + double *vwall, double rwall, double *v, + double *f, double *omega, double *torque, + double radius, double meff, double *shear) +{ + double r,vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; + double wr1,wr2,wr3,damp,ccel,vtr1,vtr2,vtr3,vrel; + double fn,fs,fs1,fs2,fs3,fx,fy,fz,tor1,tor2,tor3; + double shrmag,rsht,polyhertz,rinv,rsqinv; + + double pois,E_eff,G_eff,rad_eff; + double a0,Fcrit,delcrit,delcritinv; + double overlap,olapsq,olapcubed,sqrtterm,tmp,keyterm,keyterm2,keyterm3; + double aovera0,foverFc; + double gammatsuji; + + double ktwist,kroll,twistcrit,rollcrit; + double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; + double magtwist,magtortwist; + double magrollsq,magroll,magrollinv,magtorroll; + + r = sqrt(rsq); + rinv = 1.0/r; + rsqinv = 1.0/rsq; + + // relative translational velocity + + vr1 = v[0] - vwall[0]; + vr2 = v[1] - vwall[1]; + vr3 = v[2] - vwall[2]; + + // normal component + + vnnr = vr1*dx + vr2*dy + vr3*dz; + vn1 = dx*vnnr / rsq; + vn2 = dy*vnnr / rsq; + vn3 = dz*vnnr / rsq; + + // tangential component + + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + + wr1 = radius*omega[0] * rinv; + wr2 = radius*omega[1] * rinv; + wr3 = radius*omega[2] * rinv; + + // normal forces = Hertzian contact + normal velocity damping + // material properties: currently assumes identical materials + + pois = E/(2.0*G) - 1.0; + E_eff=0.5*E/(1.0-pois*pois); + G_eff=G/(4.0-2.0*pois); + + // rwall = 0 is infinite wall radius of curvature (flat wall) + + if (rwall == 0) rad_eff = radius; + else rad_eff = radius*rwall/(radius+rwall); + + Fcrit = rad_eff * (3.0 * M_PI * SurfEnergy); + a0=pow(9.0*M_PI*SurfEnergy*rad_eff*rad_eff/E_eff,1.0/3.0); + delcrit = 1.0/rad_eff*(0.5 * a0*a0/pow(6.0,1.0/3.0)); + delcritinv = 1.0/delcrit; + + overlap = (radius-r) * delcritinv; + olapsq = overlap*overlap; + olapcubed = olapsq*overlap; + sqrtterm = sqrt(1.0 + olapcubed); + tmp = 2.0 + olapcubed + 2.0*sqrtterm; + keyterm = pow(tmp,THIRD); + keyterm2 = olapsq/keyterm; + keyterm3 = sqrt(overlap + keyterm2 + keyterm); + aovera0 = pow(6.0,-TWOTHIRDS) * (keyterm3 + + sqrt(2.0*overlap - keyterm2 - keyterm + 4.0/keyterm3)); + foverFc = 4.0*((aovera0*aovera0*aovera0) - pow(aovera0,1.5)); + ccel = Fcrit*foverFc*rinv; + + // damp = meff*gamman*vnnr*rsqinv; + // ccel = kn*(radius-r)*rinv - damp; + // polyhertz = sqrt((radius-r)*radius); + // ccel *= polyhertz; + + // use Tsuji et al form + + polyhertz = 1.2728- 4.2783*0.9 + 11.087*0.9*0.9 - 22.348*0.9*0.9*0.9 + + 27.467*0.9*0.9*0.9*0.9 - 18.022*0.9*0.9*0.9*0.9*0.9 + + 4.8218*0.9*0.9*0.9*0.9*0.9*0.9; + + gammatsuji = 0.2*sqrt(meff*kn); + damp = gammatsuji*vnnr/rsq; + ccel = ccel - polyhertz * damp; + + // relative velocities + + vtr1 = vt1 - (dz*wr2-dy*wr3); + vtr2 = vt2 - (dx*wr3-dz*wr1); + vtr3 = vt3 - (dy*wr1-dx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + // shear history effects + + if (shearupdate) { + shear[0] += vtr1*dt; + shear[1] += vtr2*dt; + shear[2] += vtr3*dt; + } + shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + shear[2]*shear[2]); + + // rotate shear displacements + + rsht = shear[0]*dx + shear[1]*dy + shear[2]*dz; + rsht = rsht*rsqinv; + if (shearupdate) { + shear[0] -= rsht*dx; + shear[1] -= rsht*dy; + shear[2] -= rsht*dz; + } + + // tangential forces = shear + tangential velocity damping + + fs1 = -polyhertz * (kt*shear[0] + meff*gammat*vtr1); + fs2 = -polyhertz * (kt*shear[1] + meff*gammat*vtr2); + fs3 = -polyhertz * (kt*shear[2] + meff*gammat*vtr3); + + kt=8.0*G_eff*a0*aovera0; + + // shear damping uses Tsuji et al form also + + fs1 = -kt*shear[0] - polyhertz*gammatsuji*vtr1; + fs2 = -kt*shear[1] - polyhertz*gammatsuji*vtr2; + fs3 = -kt*shear[2] - polyhertz*gammatsuji*vtr3; + + // rescale frictional displacements and forces if needed + + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + fn = xmu * fabs(ccel*r + 2.0*Fcrit); + + if (fs > fn) { + if (shrmag != 0.0) { + shear[0] = (fn/fs) * (shear[0] + polyhertz*gammatsuji*vtr1/kt) - + polyhertz*gammatsuji*vtr1/kt; + shear[1] = (fn/fs) * (shear[1] + polyhertz*gammatsuji*vtr2/kt) - + polyhertz*gammatsuji*vtr2/kt; + shear[2] = (fn/fs) * (shear[2] + polyhertz*gammatsuji*vtr3/kt) - + polyhertz*gammatsuji*vtr3/kt; + fs1 *= fn/fs ; + fs2 *= fn/fs; + fs3 *= fn/fs; + } else fs1 = fs2 = fs3 = 0.0; + } + + // calculate twisting and rolling components of torque + // NOTE: this assumes spheres! + + relrot1 = omega[0]; + relrot2 = omega[1]; + relrot3 = omega[2]; + + // rolling velocity + // NOTE: this assumes mondisperse spheres! + + vrl1 = -rad_eff*rinv * (relrot2*dz - relrot3*dy); + vrl2 = -rad_eff*rinv * (relrot3*dx - relrot1*dz); + vrl3 = -rad_eff*rinv * (relrot1*dy - relrot2*dx); + vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); + if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; + else vrlmaginv = 0.0; + + // bond history effects + + shear[3] += vrl1*dt; + shear[4] += vrl2*dt; + shear[5] += vrl3*dt; + + // rotate bonded displacements correctly + + double rlt = shear[3]*dx + shear[4]*dy + shear[5]*dz; + rlt /= rsq; + shear[3] -= rlt*dx; + shear[4] -= rlt*dy; + shear[5] -= rlt*dz; + + // twisting torque + + magtwist = rinv*(relrot1*dx + relrot2*dy + relrot3*dz); + shear[6] += magtwist*dt; + + ktwist = 0.5*kt*(a0*aovera0)*(a0*aovera0); + magtortwist = -ktwist*shear[6] - + 0.5*polyhertz*gammatsuji*(a0*aovera0)*(a0*aovera0)*magtwist; + + twistcrit=TWOTHIRDS*a0*aovera0*Fcrit; + if (fabs(magtortwist) > twistcrit) + magtortwist = -twistcrit * magtwist/fabs(magtwist); + + // rolling torque + + magrollsq = shear[3]*shear[3] + shear[4]*shear[4] + shear[5]*shear[5]; + magroll = sqrt(magrollsq); + if (magroll != 0.0) magrollinv = 1.0/magroll; + else magrollinv = 0.0; + + kroll = 1.0*4.0*Fcrit*pow(aovera0,1.5); + magtorroll = -kroll*magroll - 0.1*gammat*vrlmag; + + rollcrit = 0.01; + if (magroll > rollcrit) magtorroll = -kroll*rollcrit; + + // forces & torques + + fx = dx*ccel + fs1; + fy = dy*ccel + fs2; + fz = dz*ccel + fs3; + + f[0] += fx; + f[1] += fy; + f[2] += fz; + + tor1 = rinv * (dy*fs3 - dz*fs2); + tor2 = rinv * (dz*fs1 - dx*fs3); + tor3 = rinv * (dx*fs2 - dy*fs1); + torque[0] -= radius*tor1; + torque[1] -= radius*tor2; + torque[2] -= radius*tor3; + + torque[0] += magtortwist * dx*rinv; + torque[1] += magtortwist * dy*rinv; + torque[2] += magtortwist * dz*rinv; + + torque[0] += magtorroll * (shear[4]*dz - shear[5]*dy)*rinv*magrollinv; + torque[1] += magtorroll * (shear[5]*dx - shear[3]*dz)*rinv*magrollinv; + torque[2] += magtorroll * (shear[3]*dy - shear[4]*dx)*rinv*magrollinv; +} + /* ---------------------------------------------------------------------- memory usage of local atom-based arrays ------------------------------------------------------------------------- */ double FixWallGran::memory_usage() { int nmax = atom->nmax; double bytes = 0.0; - if (history) bytes += 3*nmax * sizeof(double); // shear history - if (fix_rigid) bytes += nmax * sizeof(int); // mass_rigid + if (history) bytes += nmax*sheardim * sizeof(double); // shear history + if (fix_rigid) bytes += nmax * sizeof(int); // mass_rigid return bytes; } /* ---------------------------------------------------------------------- allocate local atom-based arrays ------------------------------------------------------------------------- */ void FixWallGran::grow_arrays(int nmax) { - if (history) memory->grow(shear,nmax,3,"fix_wall_gran:shear"); + if (history) memory->grow(shearone,nmax,sheardim,"fix_wall_gran:shearone"); } /* ---------------------------------------------------------------------- copy values within local atom-based arrays ------------------------------------------------------------------------- */ void FixWallGran::copy_arrays(int i, int j, int delflag) { - if (history) { - shear[j][0] = shear[i][0]; - shear[j][1] = shear[i][1]; - shear[j][2] = shear[i][2]; - } + if (history) + for (int m = 0; m < sheardim; m++) + shearone[j][m] = shearone[i][m]; } /* ---------------------------------------------------------------------- initialize one atom's array values, called when atom is created ------------------------------------------------------------------------- */ void FixWallGran::set_arrays(int i) { - if (history) shear[i][0] = shear[i][1] = shear[i][2] = 0.0; + if (history) + for (int m = 0; m < sheardim; m++) + shearone[i][m] = 0; } /* ---------------------------------------------------------------------- pack values in local atom-based arrays for exchange with another proc ------------------------------------------------------------------------- */ int FixWallGran::pack_exchange(int i, double *buf) { if (!history) return 0; - buf[0] = shear[i][0]; - buf[1] = shear[i][1]; - buf[2] = shear[i][2]; - return 3; + int n = 0; + for (int m = 0; m < sheardim; m++) + buf[n++] = shearone[i][m]; + return n; } /* ---------------------------------------------------------------------- unpack values into local atom-based arrays after exchange ------------------------------------------------------------------------- */ int FixWallGran::unpack_exchange(int nlocal, double *buf) { if (!history) return 0; - shear[nlocal][0] = buf[0]; - shear[nlocal][1] = buf[1]; - shear[nlocal][2] = buf[2]; - return 3; + int n = 0; + for (int m = 0; m < sheardim; m++) + shearone[nlocal][m] = buf[n++]; + return n; } /* ---------------------------------------------------------------------- pack values in local atom-based arrays for restart file ------------------------------------------------------------------------- */ int FixWallGran::pack_restart(int i, double *buf) { if (!history) return 0; - int m = 0; - buf[m++] = 4; - buf[m++] = shear[i][0]; - buf[m++] = shear[i][1]; - buf[m++] = shear[i][2]; - return m; + int n = 0; + buf[n++] = sheardim + 1; + for (int m = 0; m < sheardim; m++) + buf[n++] = shearone[i][m]; + return n; } /* ---------------------------------------------------------------------- unpack values from atom->extra array to restart the fix ------------------------------------------------------------------------- */ void FixWallGran::unpack_restart(int nlocal, int nth) { - double **extra = atom->extra; - if (!history) return; + double **extra = atom->extra; + // skip to Nth set of extra values int m = 0; for (int i = 0; i < nth; i++) m += static_cast (extra[nlocal][m]); m++; - shear[nlocal][0] = extra[nlocal][m++]; - shear[nlocal][1] = extra[nlocal][m++]; - shear[nlocal][2] = extra[nlocal][m++]; + for (int i = 0; i < sheardim; i++) + shearone[nlocal][i] = extra[nlocal][m++]; } /* ---------------------------------------------------------------------- maxsize of any atom's restart data ------------------------------------------------------------------------- */ int FixWallGran::maxsize_restart() { if (!history) return 0; - return 4; + return 1 + sheardim; } /* ---------------------------------------------------------------------- size of atom nlocal's restart data ------------------------------------------------------------------------- */ int FixWallGran::size_restart(int nlocal) { if (!history) return 0; - return 4; + return 1 + sheardim; } /* ---------------------------------------------------------------------- */ void FixWallGran::reset_dt() { dt = update->dt; } diff --git a/src/GRANULAR/fix_wall_gran.h b/src/GRANULAR/fix_wall_gran.h index df15cd739..e9b6a73b9 100644 --- a/src/GRANULAR/fix_wall_gran.h +++ b/src/GRANULAR/fix_wall_gran.h @@ -1,117 +1,125 @@ /* -*- 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. ------------------------------------------------------------------------- */ #ifdef FIX_CLASS FixStyle(wall/gran,FixWallGran) #else #ifndef LMP_FIX_WALL_GRAN_H #define LMP_FIX_WALL_GRAN_H #include "fix.h" namespace LAMMPS_NS { class FixWallGran : public Fix { public: FixWallGran(class LAMMPS *, int, char **); virtual ~FixWallGran(); int setmask(); - void init(); + virtual void init(); void setup(int); virtual void post_force(int); virtual void post_force_respa(int, int, int); - double memory_usage(); - void grow_arrays(int); - void copy_arrays(int, int, int); - void set_arrays(int); - int pack_exchange(int, double *); - int unpack_exchange(int, double *); - int pack_restart(int, double *); - void unpack_restart(int, int); - int size_restart(int); - int maxsize_restart(); + virtual double memory_usage(); + virtual void grow_arrays(int); + virtual void copy_arrays(int, int, int); + virtual void set_arrays(int); + virtual int pack_exchange(int, double *); + virtual int unpack_exchange(int, double *); + virtual int pack_restart(int, double *); + virtual void unpack_restart(int, int); + virtual int size_restart(int); + virtual int maxsize_restart(); void reset_dt(); + void hooke(double, double, double, double, double *, + double *, double *, double *, double *, double, double); + void hooke_history(double, double, double, double, double *, + double *, double *, double *, double *, double, double, + double *); + void hertz_history(double, double, double, double, double *, double, + double *, double *, double *, double *, double, double, + double *); + void bonded_history(double, double, double, double, double *, double, + double *, double *, double *, double *, double, double, + double *); + protected: - int wallstyle,pairstyle,history,wiggle,wshear,axis; + int wallstyle,wiggle,wshear,axis; + int pairstyle,nlevels_respa; + bigint time_origin; double kn,kt,gamman,gammat,xmu; + double E,G,SurfEnergy; double lo,hi,cylradius; double amplitude,period,omega,vshear; double dt; - int nlevels_respa; - int time_origin; + char *idregion; + + int history; // if particle/wall interaction stores history + int shearupdate; // flag for whether shear history is updated + int sheardim; // # of shear history values per contact - // shear history values + // shear history for single contact per particle - double **shear; - int shearupdate; + double **shearone; // rigid body masses for use in granular interactions class Fix *fix_rigid; // ptr to rigid body fix, NULL if none double *mass_rigid; // rigid mass for owned+ghost atoms int nmax; // allocated size of mass_rigid - - void hooke(double, double, double, double, double *, - double *, double *, double *, double *, double, double); - void hooke_history(double, double, double, double, double *, - double *, double *, double *, double *, double, double, - double *); - void hertz_history(double, double, double, double, double *, - double *, double *, double *, double *, double, double, - double *); }; } #endif #endif /* ERROR/WARNING messages: E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. E: Fix wall/gran requires atom style sphere Self-explanatory. E: Cannot use wall in periodic dimension Self-explanatory. E: Cannot wiggle and shear fix wall/gran Cannot specify both options at the same time. E: Invalid wiggle direction for fix wall/gran Self-explanatory. E: Invalid shear direction for fix wall/gran Self-explanatory. E: Fix wall/gran is incompatible with Pair style Must use a granular pair style to define the parameters needed for this fix. */ diff --git a/src/GRANULAR/fix_wall_gran_region.cpp b/src/GRANULAR/fix_wall_gran_region.cpp new file mode 100644 index 000000000..3ed7cf3d9 --- /dev/null +++ b/src/GRANULAR/fix_wall_gran_region.cpp @@ -0,0 +1,548 @@ +/* ---------------------------------------------------------------------- + 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. + ------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: Dan Bolintineanu (SNL) +------------------------------------------------------------------------- */ + +#include "math.h" +#include "stdlib.h" +#include "string.h" +#include "fix_wall_gran_region.h" +#include "region.h" +#include "atom.h" +#include "domain.h" +#include "update.h" +#include "force.h" +#include "pair.h" +#include "modify.h" +#include "respa.h" +#include "math_const.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; +using namespace FixConst; +using namespace MathConst; + +// same as FixWallGran + +enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY,BONDED_HISTORY}; + +#define BIG 1.0e20 + +/* ---------------------------------------------------------------------- */ + +FixWallGranRegion::FixWallGranRegion(LAMMPS *lmp, int narg, char **arg) : + FixWallGran(lmp, narg, arg) +{ + restart_global = 1; + motion_resetflag = 0; + + int iregion = domain->find_region(idregion); + if (iregion == -1) + error->all(FLERR,"Region ID for fix wall/gran/region does not exist"); + region = domain->regions[iregion]; + region_style = new char[strlen(region->style)+1]; + strcpy(region_style,region->style); + nregion = region->nregion; + + tmax = domain->regions[iregion]->tmax; + c2r = new int[tmax]; + + // re-allocate atom-based arrays with nshear + // do not register with Atom class, since parent class did that + + memory->destroy(shearone); + shearone = NULL; + + ncontact = NULL; + walls = NULL; + shearmany = NULL; + grow_arrays(atom->nmax); + + // initialize shear history as if particle is not touching region + + if (history) { + int nlocal = atom->nlocal; + for (int i = 0; i < nlocal; i++) + ncontact[i] = 0; + } +} + +/* ---------------------------------------------------------------------- */ + +FixWallGranRegion::~FixWallGranRegion() +{ + delete [] c2r; + memory->destroy(ncontact); + memory->destroy(walls); + memory->destroy(shearmany); +} + +/* ---------------------------------------------------------------------- */ + +void FixWallGranRegion::init() +{ + FixWallGran::init(); + + int iregion = domain->find_region(idregion); + if (iregion == -1) + error->all(FLERR,"Region ID for fix wall/gran/region does not exist"); + region = domain->regions[iregion]; + + // region displacement and orientation theta at previous step + // check if region properties changed between runs + + if (motion_resetflag) { + if (comm->me == 0) { + char str[128]; + sprintf(str,"Properties for region %s do not match restart file, " + "resetting its motion",idregion); + error->warning(FLERR,str); + } + region->reset_vel(); + } +} + + +/* ---------------------------------------------------------------------- */ + +void FixWallGranRegion::post_force(int vflag) +{ + int i,m,nc,iwall; + double rinv,fx,fy,fz,tooclose; + double dx,dy,dz,rsq,meff; + double xc[3],vwall[3]; + + // do not update shear history during setup + + shearupdate = 1; + if (update->setupflag) shearupdate = 0; + + // if just reneighbored: + // update rigid body masses for owned atoms if using FixRigid + // body[i] = which body atom I is in, -1 if none + // mass_body = mass of each rigid body + + if (neighbor->ago == 0 && fix_rigid) { + int tmp; + int *body = (int *) fix_rigid->extract("body",tmp); + double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); + if (atom->nmax > nmax) { + memory->destroy(mass_rigid); + nmax = atom->nmax; + memory->create(mass_rigid,nmax,"wall/gran:mass_rigid"); + } + int nlocal = atom->nlocal; + for (i = 0; i < nlocal; i++) { + if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; + else mass_rigid[i] = 0.0; + } + } + + int regiondynamic = region->dynamic_check(); + if (!regiondynamic) vwall[0] = vwall[1] = vwall[2] = 0.0; + + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + double **omega = atom->omega; + double **torque = atom->torque; + double *radius = atom->radius; + double *rmass = atom->rmass; + + int *mask = atom->mask; + int nlocal = atom->nlocal; + + // set current motion attributes of region + // set_velocity() also updates prev to current step + + if (regiondynamic) { + region->prematch(); + region->set_velocity(); + } + + for (i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) { + if (!region->match(x[i][0],x[i][1],x[i][2])) continue; + + nc = region->surface(x[i][0],x[i][1],x[i][2],radius[i]); + if (nc > tmax) + error->one(FLERR,"Too many wall/gran/region contacts for one particle"); + + // shear history maintenance + // update ncontact,walls,shear2many for particle I + // to reflect new and persistent shear history values + // also set c2r[] = indices into region->contact[] for each of N contacts + // process zero or one contact here, otherwise invoke update_contacts() + + if (history) { + if (nc == 0) { + ncontact[i] = 0; + continue; + } + if (nc == 1) { + c2r[0] = 0; + iwall = region->contact[0].iwall; + if (ncontact[i] == 0) { + ncontact[i] = 1; + walls[i][0] = iwall; + for (m = 0; m < sheardim; m++) + shearmany[i][0][m] = 0.0; + } else if (ncontact[i] > 1 || iwall != walls[i][0]) + update_contacts(i,nc); + } else update_contacts(i,nc); + } + + // process current contacts + + for (int ic = 0; ic < nc; ic++) { + + // rsq = squared contact distance + // xc = contact point + + rsq = region->contact[ic].r*region->contact[ic].r; + + dx = region->contact[ic].delx; + dy = region->contact[ic].dely; + dz = region->contact[ic].delz; + + if (regiondynamic) region->velocity_contact(vwall, x[i], ic); + + + // meff = effective mass of sphere + // if I is part of rigid body, use body mass + + meff = rmass[i]; + if (fix_rigid && mass_rigid[i] > 0.0) meff = mass_rigid[i]; + + // invoke sphere/wall interaction + + if (pairstyle == HOOKE) + hooke(rsq,dx,dy,dz,vwall,v[i],f[i], + omega[i],torque[i],radius[i],meff); + else if (pairstyle == HOOKE_HISTORY) + hooke_history(rsq,dx,dy,dz,vwall,v[i],f[i], + omega[i],torque[i],radius[i],meff, + shearmany[i][c2r[ic]]); + else if (pairstyle == HERTZ_HISTORY) + hertz_history(rsq,dx,dy,dz,vwall,region->contact[ic].radius, + v[i],f[i],omega[i],torque[i], + radius[i],meff,shearmany[i][c2r[ic]]); + else if (pairstyle == BONDED_HISTORY) + bonded_history(rsq,dx,dy,dz,vwall,region->contact[ic].radius, + v[i],f[i],omega[i],torque[i], + radius[i],meff,shearmany[i][c2r[ic]]); + } + } + } +} + +/* ---------------------------------------------------------------------- + update contact info in ncontact, walls, shear2many for particle I + based on ncontacts[i] old contacts and N new contacts + matched via their associated walls + delete/zero shear history for broken/new contacts + also set c2r[i] = index of Ith contact in region list of contacts +------------------------------------------------------------------------- */ + +void FixWallGranRegion::update_contacts(int i, int nc) +{ + int j,m,iold,nold,ilast,inew,iadd,iwall; + + // loop over old contacts + // if not in new contact list: + // delete old contact by copying last contact over it + + iold = 0; + while (iold < ncontact[i]) { + for (m = 0; m < nc; m++) + if (region->contact[m].iwall = walls[i][iold]) break; + if (m < nc) { + ilast = ncontact[i]-1; + for (j = 0; j < sheardim; j++) + shearmany[i][iold][j] = shearmany[i][ilast][j]; + walls[i][iold] = walls[i][ilast]; + ncontact[i]--; + } else iold++; + } + + // loop over new contacts + // if not in newly compressed contact list of length nold: + // add it with zeroed shear history + // set all values in c2r + + nold = ncontact[i]; + + for (inew = 0; inew < nc; inew++) { + iwall = region->contact[inew].iwall; + for (m = 0; m < nold; m++) + if (walls[i][m] == iwall) break; + if (m < nold) c2r[m] = inew; + else { + iadd = ncontact[i]; + + c2r[iadd] = inew; + for (j = 0; j < sheardim; j++) + shearmany[i][iadd][j] = 0.0; + walls[i][iadd] = iwall; + ncontact[i]++; + } + } +} + +/* ---------------------------------------------------------------------- + memory usage of local atom-based arrays +------------------------------------------------------------------------- */ + +double FixWallGranRegion::memory_usage() +{ + int nmax = atom->nmax; + double bytes = 0.0; + if (history) { // shear history + bytes += nmax * sizeof(int); // ncontact + bytes += nmax*tmax * sizeof(int); // walls + bytes += nmax*tmax*sheardim * sizeof(double); // shearmany + } + if (fix_rigid) bytes += nmax * sizeof(int); // mass_rigid + return bytes; +} + +/* ---------------------------------------------------------------------- + allocate local atom-based arrays +------------------------------------------------------------------------- */ + +void FixWallGranRegion::grow_arrays(int nmax) +{ + if (history) { + memory->grow(ncontact,nmax,"fix_wall_gran:ncontact"); + memory->grow(walls,nmax,tmax,"fix_wall_gran:walls"); + memory->grow(shearmany,nmax,tmax,sheardim,"fix_wall_gran:shearmany"); + } +} + +/* ---------------------------------------------------------------------- + copy values within local atom-based arrays +------------------------------------------------------------------------- */ + +void FixWallGranRegion::copy_arrays(int i, int j, int delflag) +{ + int m,n,iwall; + + if (!history) return; + + n = ncontact[i]; + + for (iwall = 0; iwall < n; iwall++) { + walls[j][iwall] = walls[i][iwall]; + for (m = 0; m < sheardim; m++) + shearmany[j][iwall][m] = shearmany[i][iwall][m]; + } + ncontact[j] = ncontact[i]; +} + +/* ---------------------------------------------------------------------- + initialize one atom's array values, called when atom is created +------------------------------------------------------------------------- */ + +void FixWallGranRegion::set_arrays(int i) +{ + if (!history) return; + ncontact[i] = 0; +} + +/* ---------------------------------------------------------------------- + pack values in local atom-based arrays for exchange with another proc +------------------------------------------------------------------------- */ + +int FixWallGranRegion::pack_exchange(int i, double *buf) +{ + int m; + + if (!history) return 0; + + int n = 0; + int count = ncontact[i]; + + buf[n++] = ubuf(count).d; + for (int iwall = 0; iwall < count; iwall++) { + buf[n++] = ubuf(walls[i][iwall]).d; + for (m = 0; m < sheardim; m++) + buf[n++] = shearmany[i][iwall][m]; + } + + return n; +} + +/* ---------------------------------------------------------------------- + unpack values into local atom-based arrays after exchange +------------------------------------------------------------------------- */ + +int FixWallGranRegion::unpack_exchange(int nlocal, double *buf) +{ + int m; + + if (!history) return 0; + + int n = 0; + int count = ncontact[nlocal] = (int) ubuf(buf[n++]).i; + + for (int iwall = 0; iwall < count; iwall++) { + walls[nlocal][iwall] = (int) ubuf(buf[n++]).i; + for (m = 0; m < sheardim; m++) + shearmany[nlocal][iwall][m] = buf[n++]; + } + + return n; +} + +/* ---------------------------------------------------------------------- + pack values in local atom-based arrays for restart file +------------------------------------------------------------------------- */ + +int FixWallGranRegion::pack_restart(int i, double *buf) +{ + int m; + + if (!history) return 0; + + int n = 1; + int count = ncontact[i]; + + buf[n++] = ubuf(count).d; + for (int iwall = 0; iwall < count; iwall++) { + buf[n++] = ubuf(walls[i][iwall]).d; + for (m = 0; m < sheardim; m++) + buf[n++] = shearmany[i][iwall][m]; + } + buf[0] = n; + return n; +} + +/* ---------------------------------------------------------------------- + unpack values from atom->extra array to restart the fix +------------------------------------------------------------------------- */ + +void FixWallGranRegion::unpack_restart(int nlocal, int nth) +{ + int k; + + if (!history) return; + + double **extra = atom->extra; + + // skip to Nth set of extra values + + int m = 0; + for (int i = 0; i < nth; i++) m += static_cast (extra[nlocal][m]); + m++; + + int count = ncontact[nlocal] = (int) ubuf(extra[nlocal][m++]).i; + for (int iwall = 0; iwall < count; iwall++) { + walls[nlocal][iwall] = (int) ubuf(extra[nlocal][m++]).i; + for (k = 0; k < sheardim; k++) + shearmany[nlocal][iwall][k] = extra[nlocal][m++]; + } +} + +/* ---------------------------------------------------------------------- + maxsize of any atom's restart data +------------------------------------------------------------------------- */ + +int FixWallGranRegion::maxsize_restart() +{ + if (!history) return 0; + return 2 + tmax*(sheardim+1); +} + +/* ---------------------------------------------------------------------- + size of atom nlocal's restart data +------------------------------------------------------------------------- */ + +int FixWallGranRegion::size_restart(int nlocal) +{ + if (!history) return 0; + return 2 + ncontact[nlocal]*(sheardim+1); +} + +/* ---------------------------------------------------------------------- + pack entire state of Fix into one write +------------------------------------------------------------------------- */ + +void FixWallGranRegion::write_restart(FILE *fp) +{ + if (comm->me) return; + int size_id_str = (strlen(region->id) + 1) * sizeof(char); + int size_style_str = (strlen(region->style) + 1) * sizeof(char); + int size_tot = sizeof(int) + size_id_str + + sizeof(int) + size_style_str + sizeof(int) + + region->size_restart*sizeof(double); + + fwrite(&size_tot,sizeof(int),1,fp); + fwrite(&size_id_str,sizeof(int),1,fp); + fwrite(region->id,sizeof(char),size_id_str,fp); + fwrite(&size_style_str,sizeof(int),1,fp); + fwrite(region->style,sizeof(char),size_style_str,fp); + fwrite(®ion->nregion,sizeof(int),1,fp); + + region->write_restart(fp); +} + +/* ---------------------------------------------------------------------- + use state info from restart file to restart the Fix +------------------------------------------------------------------------- */ + +void FixWallGranRegion::restart(char *buf) +{ + int n = 0; + int size_id_str = buf[n]; + n += sizeof(int); + char *region_id_restart = new char[size_id_str]; + for (int i = 0; i < size_id_str; i++){ + region_id_restart[i] = buf[n++]; + } + + int size_style_str = buf[n]; + n += sizeof(int); + char *region_style_restart = new char[size_style_str]; + for (int i = 0; i < size_style_str; i++) + region_style_restart[i] = buf[n++]; + + int nregion_restart = buf[n]; + n += sizeof(int); + + if (check_consistent_region(region,region_id_restart, + region_style_restart,nregion_restart)) + region->restart(buf,n); + else motion_resetflag = 1; + + delete [] region_id_restart; + delete [] region_style_restart; +} + + +/* ---------------------------------------------------------------------- + check that region id/style/number of sub-regions are consistent +------------------------------------------------------------------------- */ + +int FixWallGranRegion::check_consistent_region(Region *region, + char* region_id, + char* region_style, int nregion) +{ + if (strcmp(region_id, region->id) != 0 || + strcmp(region_style, region->style) != 0 || + nregion != region->nregion) + return 0; + return 1; +} diff --git a/src/GRANULAR/fix_wall_gran.h b/src/GRANULAR/fix_wall_gran_region.h similarity index 56% copy from src/GRANULAR/fix_wall_gran.h copy to src/GRANULAR/fix_wall_gran_region.h index df15cd739..d7bc8be53 100644 --- a/src/GRANULAR/fix_wall_gran.h +++ b/src/GRANULAR/fix_wall_gran_region.h @@ -1,117 +1,106 @@ /* -*- 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. ------------------------------------------------------------------------- */ #ifdef FIX_CLASS -FixStyle(wall/gran,FixWallGran) +FixStyle(wall/gran/region,FixWallGranRegion) #else -#ifndef LMP_FIX_WALL_GRAN_H -#define LMP_FIX_WALL_GRAN_H +#ifndef LMP_FIX_WALL_GRAN_REGION_H +#define LMP_FIX_WALL_GRAN_REGION_H -#include "fix.h" +#include "fix_wall_gran.h" namespace LAMMPS_NS { -class FixWallGran : public Fix { +class FixWallGranRegion : public FixWallGran { public: - FixWallGran(class LAMMPS *, int, char **); - virtual ~FixWallGran(); - int setmask(); + FixWallGranRegion(class LAMMPS *, int, char **); + ~FixWallGranRegion(); + void post_force(int); + void write_restart(FILE *); + void restart(char* ); void init(); - void setup(int); - virtual void post_force(int); - virtual void post_force_respa(int, int, int); - + double memory_usage(); void grow_arrays(int); void copy_arrays(int, int, int); void set_arrays(int); int pack_exchange(int, double *); int unpack_exchange(int, double *); int pack_restart(int, double *); void unpack_restart(int, int); int size_restart(int); int maxsize_restart(); - void reset_dt(); - - protected: - int wallstyle,pairstyle,history,wiggle,wshear,axis; - double kn,kt,gamman,gammat,xmu; - double lo,hi,cylradius; - double amplitude,period,omega,vshear; - double dt; - int nlevels_respa; - int time_origin; - - // shear history values - - double **shear; - int shearupdate; - - // rigid body masses for use in granular interactions - - class Fix *fix_rigid; // ptr to rigid body fix, NULL if none - double *mass_rigid; // rigid mass for owned+ghost atoms - int nmax; // allocated size of mass_rigid - - void hooke(double, double, double, double, double *, - double *, double *, double *, double *, double, double); - void hooke_history(double, double, double, double, double *, - double *, double *, double *, double *, double, double, - double *); - void hertz_history(double, double, double, double, double *, - double *, double *, double *, double *, double, double, - double *); + + private: + class Region *region; + char *region_style; + int nregion; + + // shear history for multiple contacts per particle + + int tmax; // max # of region walls one particle can touch + int *ncontact; // # of shear contacts per particle + int **walls; // which wall each contact is with + double ***shearmany; // shear history per particle per contact + int *c2r; // contact to region mapping + // c2r[i] = index of Ith contact in + // region-contact[] list of contacts + int motion_resetflag; // used by restart to indicate that region + // vel info is to be reset + + void update_contacts(int, int); + int check_consistent_region(Region *, char*, char*, int); }; } #endif #endif /* ERROR/WARNING messages: E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. E: Fix wall/gran requires atom style sphere Self-explanatory. E: Cannot use wall in periodic dimension Self-explanatory. E: Cannot wiggle and shear fix wall/gran Cannot specify both options at the same time. E: Invalid wiggle direction for fix wall/gran Self-explanatory. E: Invalid shear direction for fix wall/gran Self-explanatory. E: Fix wall/gran is incompatible with Pair style Must use a granular pair style to define the parameters needed for this fix. */ diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index 4d343367f..577eff236 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -1,268 +1,275 @@ /* ---------------------------------------------------------------------- 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 #include "atom_kokkos.h" #include "atom_vec.h" #include "atom_vec_kokkos.h" #include "comm_kokkos.h" #include "update.h" #include "domain.h" #include "atom_masks.h" #include "memory.h" #include "error.h" +#include "kokkos.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ AtomKokkos::AtomKokkos(LAMMPS *lmp) : Atom(lmp) {} /* ---------------------------------------------------------------------- */ AtomKokkos::~AtomKokkos() { memory->destroy_kokkos(k_tag, tag); memory->destroy_kokkos(k_mask, mask); memory->destroy_kokkos(k_type, type); memory->destroy_kokkos(k_image, image); memory->destroy_kokkos(k_molecule, molecule); memory->destroy_kokkos(k_x, x); memory->destroy_kokkos(k_v, v); memory->destroy_kokkos(k_f, f); memory->destroy_kokkos(k_mass, mass); memory->destroy_kokkos(k_q, q); memory->destroy_kokkos(k_radius, radius); memory->destroy_kokkos(k_rmass, rmass); memory->destroy_kokkos(k_omega, omega); memory->destroy_kokkos(k_torque, torque); memory->destroy_kokkos(k_nspecial, nspecial); memory->destroy_kokkos(k_special, special); memory->destroy_kokkos(k_num_bond, num_bond); memory->destroy_kokkos(k_bond_type, bond_type); memory->destroy_kokkos(k_bond_atom, bond_atom); memory->destroy_kokkos(k_num_angle, num_angle); memory->destroy_kokkos(k_angle_type, angle_type); memory->destroy_kokkos(k_angle_atom1, angle_atom1); memory->destroy_kokkos(k_angle_atom2, angle_atom2); memory->destroy_kokkos(k_angle_atom3, angle_atom3); memory->destroy_kokkos(k_num_dihedral, num_dihedral); memory->destroy_kokkos(k_dihedral_type, dihedral_type); memory->destroy_kokkos(k_dihedral_atom1, dihedral_atom1); memory->destroy_kokkos(k_dihedral_atom2, dihedral_atom2); memory->destroy_kokkos(k_dihedral_atom3, dihedral_atom3); memory->destroy_kokkos(k_dihedral_atom4, dihedral_atom4); memory->destroy_kokkos(k_num_improper, num_improper); memory->destroy_kokkos(k_improper_type, improper_type); memory->destroy_kokkos(k_improper_atom1, improper_atom1); memory->destroy_kokkos(k_improper_atom2, improper_atom2); memory->destroy_kokkos(k_improper_atom3, improper_atom3); memory->destroy_kokkos(k_improper_atom4, improper_atom4); } /* ---------------------------------------------------------------------- */ void AtomKokkos::sync(const ExecutionSpace space, unsigned int mask) { + if (space == Device && lmp->kokkos->auto_sync) + ((AtomVecKokkos *) avec)->modified(Host,mask); + ((AtomVecKokkos *) avec)->sync(space,mask); } /* ---------------------------------------------------------------------- */ void AtomKokkos::modified(const ExecutionSpace space, unsigned int mask) { ((AtomVecKokkos *) avec)->modified(space,mask); + + if (space == Device && lmp->kokkos->auto_sync) + ((AtomVecKokkos *) avec)->sync(Host,mask); } void AtomKokkos::sync_overlapping_device(const ExecutionSpace space, unsigned int mask) { ((AtomVecKokkos *) avec)->sync_overlapping_device(space,mask); } /* ---------------------------------------------------------------------- */ void AtomKokkos::allocate_type_arrays() { if (avec->mass_type) { k_mass = DAT::tdual_float_1d("Mass",ntypes+1); mass = k_mass.h_view.ptr_on_device(); mass_setflag = new int[ntypes+1]; for (int itype = 1; itype <= ntypes; itype++) mass_setflag[itype] = 0; k_mass.modify(); } } /* ---------------------------------------------------------------------- */ void AtomKokkos::sort() { int i,m,n,ix,iy,iz,ibin,empty; // set next timestep for sorting to take place nextsort = (update->ntimestep/sortfreq)*sortfreq + sortfreq; // re-setup sort bins if needed if (domain->box_change) setup_sort_bins(); if (nbins == 1) return; // reallocate per-atom vectors if needed if (atom->nmax > maxnext) { memory->destroy(next); memory->destroy(permute); maxnext = atom->nmax; memory->create(next,maxnext,"atom:next"); memory->create(permute,maxnext,"atom:permute"); } // insure there is one extra atom location at end of arrays for swaps if (nlocal == nmax) avec->grow(0); sync(Host,ALL_MASK); modified(Host,ALL_MASK); // bin atoms in reverse order so linked list will be in forward order for (i = 0; i < nbins; i++) binhead[i] = -1; HAT::t_x_array_const h_x = k_x.view(); for (i = nlocal-1; i >= 0; i--) { ix = static_cast ((h_x(i,0)-bboxlo[0])*bininvx); iy = static_cast ((h_x(i,1)-bboxlo[1])*bininvy); iz = static_cast ((h_x(i,2)-bboxlo[2])*bininvz); ix = MAX(ix,0); iy = MAX(iy,0); iz = MAX(iz,0); ix = MIN(ix,nbinx-1); iy = MIN(iy,nbiny-1); iz = MIN(iz,nbinz-1); ibin = iz*nbiny*nbinx + iy*nbinx + ix; next[i] = binhead[ibin]; binhead[ibin] = i; } // permute = desired permutation of atoms // permute[I] = J means Ith new atom will be Jth old atom n = 0; for (m = 0; m < nbins; m++) { i = binhead[m]; while (i >= 0) { permute[n++] = i; i = next[i]; } } // current = current permutation, just reuse next vector // current[I] = J means Ith current atom is Jth old atom int *current = next; for (i = 0; i < nlocal; i++) current[i] = i; // reorder local atom list, when done, current = permute // perform "in place" using copy() to extra atom location at end of list // inner while loop processes one cycle of the permutation // copy before inner-loop moves an atom to end of atom list // copy after inner-loop moves atom at end of list back into list // empty = location in atom list that is currently empty for (i = 0; i < nlocal; i++) { if (current[i] == permute[i]) continue; avec->copy(i,nlocal,0); empty = i; while (permute[empty] != i) { avec->copy(permute[empty],empty,0); empty = current[empty] = permute[empty]; } avec->copy(nlocal,empty,0); current[empty] = permute[empty]; } // sanity check that current = permute //int flag = 0; //for (i = 0; i < nlocal; i++) // if (current[i] != permute[i]) flag = 1; //int flagall; //MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); //if (flagall) errorX->all(FLERR,"Atom sort did not operate correctly"); } /* ---------------------------------------------------------------------- reallocate memory to the pointer selected by the mask ------------------------------------------------------------------------- */ void AtomKokkos::grow(unsigned int mask){ if (mask & SPECIAL_MASK){ memory->destroy_kokkos(k_special, special); sync(Device, mask); modified(Device, mask); memory->grow_kokkos(k_special,special,nmax,maxspecial,"atom:special"); avec->grow_reset(); sync(Host, mask); } } /* ---------------------------------------------------------------------- */ void AtomKokkos::deallocate_topology() { memory->destroy_kokkos(k_bond_type, bond_type); memory->destroy_kokkos(k_bond_atom, bond_atom); memory->destroy_kokkos(k_angle_type, angle_type); memory->destroy_kokkos(k_angle_atom1, angle_atom1); memory->destroy_kokkos(k_angle_atom2, angle_atom2); memory->destroy_kokkos(k_angle_atom3, angle_atom3); memory->destroy_kokkos(k_dihedral_type, dihedral_type); memory->destroy_kokkos(k_dihedral_atom1, dihedral_atom1); memory->destroy_kokkos(k_dihedral_atom2, dihedral_atom2); memory->destroy_kokkos(k_dihedral_atom3, dihedral_atom3); memory->destroy_kokkos(k_dihedral_atom4, dihedral_atom4); memory->destroy_kokkos(k_improper_type, improper_type); memory->destroy_kokkos(k_improper_atom1, improper_atom1); memory->destroy_kokkos(k_improper_atom2, improper_atom2); memory->destroy_kokkos(k_improper_atom3, improper_atom3); memory->destroy_kokkos(k_improper_atom4, improper_atom4); } /* ---------------------------------------------------------------------- perform sync and modify for each of 2 masks called by individual styles to override default sync/modify calls done at higher levels (Verlet,Modify,etc) ------------------------------------------------------------------------- */ void AtomKokkos::sync_modify(ExecutionSpace execution_space, unsigned int datamask_read, unsigned int datamask_modify) { sync(execution_space,datamask_read); modified(execution_space,datamask_modify); } AtomVec *AtomKokkos::new_avec(const char *style, int trysuffix, int &sflag) { AtomVec* avec = Atom::new_avec(style,trysuffix,sflag); if (!avec->kokkosable) error->all(FLERR,"KOKKOS package requires a kokkos enabled atom_style"); return avec; } diff --git a/src/KOKKOS/fix_deform_kokkos.cpp b/src/KOKKOS/fix_deform_kokkos.cpp index b3316022f..529532073 100644 --- a/src/KOKKOS/fix_deform_kokkos.cpp +++ b/src/KOKKOS/fix_deform_kokkos.cpp @@ -1,375 +1,376 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Pieter in 't Veld (SNL) ------------------------------------------------------------------------- */ #include #include #include #include "fix_deform_kokkos.h" #include "atom_kokkos.h" #include "update.h" #include "comm.h" #include "irregular.h" #include "domain_kokkos.h" #include "lattice.h" #include "force.h" #include "modify.h" #include "math_const.h" #include "kspace.h" #include "input.h" #include "variable.h" #include "error.h" #include "atom_masks.h" using namespace LAMMPS_NS; using namespace FixConst; using namespace MathConst; enum{NONE,FINAL,DELTA,SCALE,VEL,ERATE,TRATE,VOLUME,WIGGLE,VARIABLE}; enum{ONE_FROM_ONE,ONE_FROM_TWO,TWO_FROM_ONE}; // same as domain.cpp, fix_nvt_sllod.cpp, compute_temp_deform.cpp enum{NO_REMAP,X_REMAP,V_REMAP}; /* ---------------------------------------------------------------------- */ FixDeformKokkos::FixDeformKokkos(LAMMPS *lmp, int narg, char **arg) : FixDeform(lmp, narg, arg) { + kokkosable = 1; domainKK = (DomainKokkos *) domain; datamask_read = EMPTY_MASK; datamask_modify = EMPTY_MASK; } /* ---------------------------------------------------------------------- box flipped on previous step reset box tilts for flipped config and create new box in domain image_flip() adjusts image flags due to box shape change induced by flip remap() puts atoms outside the new box back into the new box perform irregular on atoms in lamda coords to migrate atoms to new procs important that image_flip comes before remap, since remap may change image flags to new values, making eqs in doc of Domain:image_flip incorrect ------------------------------------------------------------------------- */ void FixDeformKokkos::pre_exchange() { if (flip == 0) return; domain->yz = set[3].tilt_target = set[3].tilt_flip; domain->xz = set[4].tilt_target = set[4].tilt_flip; domain->xy = set[5].tilt_target = set[5].tilt_flip; domain->set_global_box(); domain->set_local_box(); domainKK->image_flip(flipxy,flipxz,flipyz); domainKK->remap_all(); domainKK->x2lamda(atom->nlocal); atomKK->sync(Host,ALL_MASK); irregular->migrate_atoms(); atomKK->modified(Host,ALL_MASK); domainKK->lamda2x(atom->nlocal); flip = 0; } /* ---------------------------------------------------------------------- */ void FixDeformKokkos::end_of_step() { int i; double delta = update->ntimestep - update->beginstep; if (delta != 0.0) delta /= update->endstep - update->beginstep; // wrap variable evaluations with clear/add if (varflag) modify->clearstep_compute(); // set new box size // for NONE, target is current box size // for TRATE, set target directly based on current time, also set h_rate // for WIGGLE, set target directly based on current time, also set h_rate // for VARIABLE, set target directly via variable eval, also set h_rate // for others except VOLUME, target is linear value between start and stop for (i = 0; i < 3; i++) { if (set[i].style == NONE) { set[i].lo_target = domain->boxlo[i]; set[i].hi_target = domain->boxhi[i]; } else if (set[i].style == TRATE) { double delt = (update->ntimestep - update->beginstep) * update->dt; set[i].lo_target = 0.5*(set[i].lo_start+set[i].hi_start) - 0.5*((set[i].hi_start-set[i].lo_start) * exp(set[i].rate*delt)); set[i].hi_target = 0.5*(set[i].lo_start+set[i].hi_start) + 0.5*((set[i].hi_start-set[i].lo_start) * exp(set[i].rate*delt)); h_rate[i] = set[i].rate * domain->h[i]; h_ratelo[i] = -0.5*h_rate[i]; } else if (set[i].style == WIGGLE) { double delt = (update->ntimestep - update->beginstep) * update->dt; set[i].lo_target = set[i].lo_start - 0.5*set[i].amplitude * sin(TWOPI*delt/set[i].tperiod); set[i].hi_target = set[i].hi_start + 0.5*set[i].amplitude * sin(TWOPI*delt/set[i].tperiod); h_rate[i] = TWOPI/set[i].tperiod * set[i].amplitude * cos(TWOPI*delt/set[i].tperiod); h_ratelo[i] = -0.5*h_rate[i]; } else if (set[i].style == VARIABLE) { double del = input->variable->compute_equal(set[i].hvar); set[i].lo_target = set[i].lo_start - 0.5*del; set[i].hi_target = set[i].hi_start + 0.5*del; h_rate[i] = input->variable->compute_equal(set[i].hratevar); h_ratelo[i] = -0.5*h_rate[i]; } else if (set[i].style != VOLUME) { set[i].lo_target = set[i].lo_start + delta*(set[i].lo_stop - set[i].lo_start); set[i].hi_target = set[i].hi_start + delta*(set[i].hi_stop - set[i].hi_start); } } // set new box size for VOLUME dims that are linked to other dims // NOTE: still need to set h_rate for these dims for (int i = 0; i < 3; i++) { if (set[i].style != VOLUME) continue; if (set[i].substyle == ONE_FROM_ONE) { set[i].lo_target = 0.5*(set[i].lo_start+set[i].hi_start) - 0.5*(set[i].vol_start / (set[set[i].dynamic1].hi_target - set[set[i].dynamic1].lo_target) / (set[set[i].fixed].hi_start-set[set[i].fixed].lo_start)); set[i].hi_target = 0.5*(set[i].lo_start+set[i].hi_start) + 0.5*(set[i].vol_start / (set[set[i].dynamic1].hi_target - set[set[i].dynamic1].lo_target) / (set[set[i].fixed].hi_start-set[set[i].fixed].lo_start)); } else if (set[i].substyle == ONE_FROM_TWO) { set[i].lo_target = 0.5*(set[i].lo_start+set[i].hi_start) - 0.5*(set[i].vol_start / (set[set[i].dynamic1].hi_target - set[set[i].dynamic1].lo_target) / (set[set[i].dynamic2].hi_target - set[set[i].dynamic2].lo_target)); set[i].hi_target = 0.5*(set[i].lo_start+set[i].hi_start) + 0.5*(set[i].vol_start / (set[set[i].dynamic1].hi_target - set[set[i].dynamic1].lo_target) / (set[set[i].dynamic2].hi_target - set[set[i].dynamic2].lo_target)); } else if (set[i].substyle == TWO_FROM_ONE) { set[i].lo_target = 0.5*(set[i].lo_start+set[i].hi_start) - 0.5*sqrt(set[i].vol_start / (set[set[i].dynamic1].hi_target - set[set[i].dynamic1].lo_target) / (set[set[i].fixed].hi_start - set[set[i].fixed].lo_start) * (set[i].hi_start - set[i].lo_start)); set[i].hi_target = 0.5*(set[i].lo_start+set[i].hi_start) + 0.5*sqrt(set[i].vol_start / (set[set[i].dynamic1].hi_target - set[set[i].dynamic1].lo_target) / (set[set[i].fixed].hi_start - set[set[i].fixed].lo_start) * (set[i].hi_start - set[i].lo_start)); } } // for triclinic, set new box shape // for NONE, target is current tilt // for TRATE, set target directly based on current time. also set h_rate // for WIGGLE, set target directly based on current time. also set h_rate // for VARIABLE, set target directly via variable eval. also set h_rate // for other styles, target is linear value between start and stop values if (triclinic) { double *h = domain->h; for (i = 3; i < 6; i++) { if (set[i].style == NONE) { if (i == 5) set[i].tilt_target = domain->xy; else if (i == 4) set[i].tilt_target = domain->xz; else if (i == 3) set[i].tilt_target = domain->yz; } else if (set[i].style == TRATE) { double delt = (update->ntimestep - update->beginstep) * update->dt; set[i].tilt_target = set[i].tilt_start * exp(set[i].rate*delt); h_rate[i] = set[i].rate * domain->h[i]; } else if (set[i].style == WIGGLE) { double delt = (update->ntimestep - update->beginstep) * update->dt; set[i].tilt_target = set[i].tilt_start + set[i].amplitude * sin(TWOPI*delt/set[i].tperiod); h_rate[i] = TWOPI/set[i].tperiod * set[i].amplitude * cos(TWOPI*delt/set[i].tperiod); } else if (set[i].style == VARIABLE) { double delta_tilt = input->variable->compute_equal(set[i].hvar); set[i].tilt_target = set[i].tilt_start + delta_tilt; h_rate[i] = input->variable->compute_equal(set[i].hratevar); } else { set[i].tilt_target = set[i].tilt_start + delta*(set[i].tilt_stop - set[i].tilt_start); } // tilt_target can be large positive or large negative value // add/subtract box lengths until tilt_target is closest to current value int idenom; if (i == 5) idenom = 0; else if (i == 4) idenom = 0; else if (i == 3) idenom = 1; double denom = set[idenom].hi_target - set[idenom].lo_target; double current = h[i]/h[idenom]; while (set[i].tilt_target/denom - current > 0.0) set[i].tilt_target -= denom; while (set[i].tilt_target/denom - current < 0.0) set[i].tilt_target += denom; if (fabs(set[i].tilt_target/denom - 1.0 - current) < fabs(set[i].tilt_target/denom - current)) set[i].tilt_target -= denom; } } if (varflag) modify->addstep_compute(update->ntimestep + nevery); // if any tilt ratios exceed 0.5, set flip = 1 and compute new tilt values // do not flip in x or y if non-periodic (can tilt but not flip) // this is b/c the box length would be changed (dramatically) by flip // if yz tilt exceeded, adjust C vector by one B vector // if xz tilt exceeded, adjust C vector by one A vector // if xy tilt exceeded, adjust B vector by one A vector // check yz first since it may change xz, then xz check comes after // flip is performed on next timestep, before reneighboring in pre-exchange() if (triclinic && flipflag) { double xprd = set[0].hi_target - set[0].lo_target; double yprd = set[1].hi_target - set[1].lo_target; double xprdinv = 1.0 / xprd; double yprdinv = 1.0 / yprd; if (set[3].tilt_target*yprdinv < -0.5 || set[3].tilt_target*yprdinv > 0.5 || set[4].tilt_target*xprdinv < -0.5 || set[4].tilt_target*xprdinv > 0.5 || set[5].tilt_target*xprdinv < -0.5 || set[5].tilt_target*xprdinv > 0.5) { set[3].tilt_flip = set[3].tilt_target; set[4].tilt_flip = set[4].tilt_target; set[5].tilt_flip = set[5].tilt_target; flipxy = flipxz = flipyz = 0; if (domain->yperiodic) { if (set[3].tilt_flip*yprdinv < -0.5) { set[3].tilt_flip += yprd; set[4].tilt_flip += set[5].tilt_flip; flipyz = 1; } else if (set[3].tilt_flip*yprdinv > 0.5) { set[3].tilt_flip -= yprd; set[4].tilt_flip -= set[5].tilt_flip; flipyz = -1; } } if (domain->xperiodic) { if (set[4].tilt_flip*xprdinv < -0.5) { set[4].tilt_flip += xprd; flipxz = 1; } if (set[4].tilt_flip*xprdinv > 0.5) { set[4].tilt_flip -= xprd; flipxz = -1; } if (set[5].tilt_flip*xprdinv < -0.5) { set[5].tilt_flip += xprd; flipxy = 1; } if (set[5].tilt_flip*xprdinv > 0.5) { set[5].tilt_flip -= xprd; flipxy = -1; } } flip = 0; if (flipxy || flipxz || flipyz) flip = 1; if (flip) next_reneighbor = update->ntimestep + 1; } } // convert atoms and rigid bodies to lamda coords if (remapflag == X_REMAP) { int nlocal = atom->nlocal; domainKK->x2lamda(nlocal); //for (i = 0; i < nlocal; i++) // if (mask[i] & groupbit) // domain->x2lamda(x[i],x[i]); if (nrigid) error->all(FLERR,"Cannot (yet) use rigid bodies with fix deform and Kokkos"); //for (i = 0; i < nrigid; i++) // modify->fix[rfix[i]]->deform(0); } // reset global and local box to new size/shape // only if deform fix is controlling the dimension if (set[0].style) { domain->boxlo[0] = set[0].lo_target; domain->boxhi[0] = set[0].hi_target; } if (set[1].style) { domain->boxlo[1] = set[1].lo_target; domain->boxhi[1] = set[1].hi_target; } if (set[2].style) { domain->boxlo[2] = set[2].lo_target; domain->boxhi[2] = set[2].hi_target; } if (triclinic) { if (set[3].style) domain->yz = set[3].tilt_target; if (set[4].style) domain->xz = set[4].tilt_target; if (set[5].style) domain->xy = set[5].tilt_target; } domain->set_global_box(); domain->set_local_box(); // convert atoms and rigid bodies back to box coords if (remapflag == X_REMAP) { int nlocal = atom->nlocal; domainKK->lamda2x(nlocal); //for (i = 0; i < nlocal; i++) // if (mask[i] & groupbit) // domain->lamda2x(x[i],x[i]); //if (nrigid) // for (i = 0; i < nrigid; i++) // modify->fix[rfix[i]]->deform(1); } // redo KSpace coeffs since box has changed if (kspace_flag) force->kspace->setup(); } diff --git a/src/KOKKOS/fix_langevin_kokkos.cpp b/src/KOKKOS/fix_langevin_kokkos.cpp index 43af4168f..b51c934c3 100644 --- a/src/KOKKOS/fix_langevin_kokkos.cpp +++ b/src/KOKKOS/fix_langevin_kokkos.cpp @@ -1,813 +1,814 @@ /* ---------------------------------------------------------------------- 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 #include #include #include "fix_langevin_kokkos.h" #include "atom_masks.h" #include "atom_kokkos.h" #include "force.h" #include "update.h" #include "respa.h" #include "error.h" #include "memory.h" #include "group.h" #include "random_mars.h" #include "compute.h" #include "comm.h" #include "modify.h" #include "input.h" #include "variable.h" using namespace LAMMPS_NS; using namespace FixConst; enum{NOBIAS,BIAS}; enum{CONSTANT,EQUAL,ATOM}; #define SINERTIA 0.4 // moment of inertia prefactor for sphere #define EINERTIA 0.2 // moment of inertia prefactor for ellipsoid /* ---------------------------------------------------------------------- */ template FixLangevinKokkos::FixLangevinKokkos(LAMMPS *lmp, int narg, char **arg) : FixLangevin(lmp, narg, arg),rand_pool(seed + comm->me) { + kokkosable = 1; atomKK = (AtomKokkos *) atom; int ntypes = atomKK->ntypes; // allocate per-type arrays for force prefactors memory->create_kokkos(k_gfactor1,gfactor1,ntypes+1,"langevin:gfactor1"); memory->create_kokkos(k_gfactor2,gfactor2,ntypes+1,"langevin:gfactor2"); memory->create_kokkos(k_ratio,ratio,ntypes+1,"langevin:ratio"); d_gfactor1 = k_gfactor1.template view(); h_gfactor1 = k_gfactor1.template view(); d_gfactor2 = k_gfactor2.template view(); h_gfactor2 = k_gfactor2.template view(); d_ratio = k_ratio.template view(); h_ratio = k_ratio.template view(); // optional args for (int i = 1; i <= ntypes; i++) ratio[i] = 1.0; k_ratio.template modify(); if(gjfflag){ nvalues = 3; grow_arrays(atomKK->nmax); atom->add_callback(0); // initialize franprev to zero for (int i = 0; i < atomKK->nlocal; i++) { franprev[i][0] = 0.0; franprev[i][1] = 0.0; franprev[i][2] = 0.0; } k_franprev.template modify(); } if(zeroflag){ k_fsumall = tdual_double_1d_3n("langevin:fsumall"); h_fsumall = k_fsumall.template view(); d_fsumall = k_fsumall.template view(); } execution_space = ExecutionSpaceFromDevice::space; datamask_read = V_MASK | F_MASK | MASK_MASK | RMASS_MASK | TYPE_MASK; datamask_modify = F_MASK; } /* ---------------------------------------------------------------------- */ template FixLangevinKokkos::~FixLangevinKokkos() { memory->destroy_kokkos(k_gfactor1,gfactor1); memory->destroy_kokkos(k_gfactor2,gfactor2); memory->destroy_kokkos(k_ratio,ratio); memory->destroy_kokkos(k_flangevin,flangevin); if(gjfflag) memory->destroy_kokkos(k_franprev,franprev); memory->destroy_kokkos(k_tforce,tforce); } /* ---------------------------------------------------------------------- */ template void FixLangevinKokkos::init() { FixLangevin::init(); if(oflag) error->all(FLERR,"Fix langevin omega is not yet implemented with kokkos"); if(ascale) error->all(FLERR,"Fix langevin angmom is not yet implemented with kokkos"); // prefactors are modified in the init k_gfactor1.template modify(); k_gfactor2.template modify(); } /* ---------------------------------------------------------------------- */ template void FixLangevinKokkos::grow_arrays(int nmax) { memory->grow_kokkos(k_franprev,franprev,nmax,3,"langevin:franprev"); d_franprev = k_franprev.template view(); h_franprev = k_franprev.template view(); } /* ---------------------------------------------------------------------- */ template void FixLangevinKokkos::post_force(int vflag) { // sync the device views which might have been modified on host atomKK->sync(execution_space,datamask_read); rmass = atomKK->rmass; f = atomKK->k_f.template view(); v = atomKK->k_v.template view(); type = atomKK->k_type.template view(); mask = atomKK->k_mask.template view(); k_gfactor1.template sync(); k_gfactor2.template sync(); k_ratio.template sync(); if(gjfflag) k_franprev.template sync(); boltz = force->boltz; dt = update->dt; mvv2e = force->mvv2e; ftm2v = force->ftm2v; fran_prop_const = sqrt(24.0*boltz/t_period/dt/mvv2e); compute_target(); // modifies tforce vector, hence sync here k_tforce.template sync(); double fsum[3],fsumall[3]; bigint count; int nlocal = atomKK->nlocal; if (zeroflag) { fsum[0] = fsum[1] = fsum[2] = 0.0; count = group->count(igroup); if (count == 0) error->all(FLERR,"Cannot zero Langevin force of 0 atoms"); } // reallocate flangevin if necessary if (tallyflag) { if (nlocal > maxatom1) { memory->destroy_kokkos(k_flangevin,flangevin); maxatom1 = atomKK->nmax; memory->create_kokkos(k_flangevin,flangevin,maxatom1,3,"langevin:flangevin"); d_flangevin = k_flangevin.template view(); h_flangevin = k_flangevin.template view(); } } // account for bias velocity if(tbiasflag == BIAS){ temperature->compute_scalar(); temperature->remove_bias_all(); // modifies velocities // if temeprature compute is kokkosized host-devcie comm won't be needed atomKK->modified(Host,V_MASK); atomKK->sync(execution_space,V_MASK); } // compute langevin force in parallel on the device FSUM s_fsum; if (tstyle == ATOM) if (gjfflag) if (tallyflag) if (tbiasflag == BIAS) if (rmass) if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else{ FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (rmass) if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else{ FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (tbiasflag == BIAS) if (rmass) if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (rmass) if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (tallyflag) if (tbiasflag == BIAS) if (rmass) if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (rmass) if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (tbiasflag == BIAS) if (rmass) if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (rmass) if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (gjfflag) if (tallyflag) if (tbiasflag == BIAS) if (rmass) if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (rmass) if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (tbiasflag == BIAS) if (rmass) if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (rmass) if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (tallyflag) if (tbiasflag == BIAS) if (rmass) if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (rmass) if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (tbiasflag == BIAS) if (rmass) if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (rmass) if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } else if (zeroflag) { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); } else { FixLangevinKokkosPostForceFunctor post_functor(this); Kokkos::parallel_for(nlocal,post_functor); } DeviceType::fence(); if(tbiasflag == BIAS){ temperature->restore_bias_all(); // modifies velocities atomKK->modified(Host,V_MASK); } // set modify flags for the views modified in post_force functor if (gjfflag) k_franprev.template modify(); if (tallyflag) k_flangevin.template modify(); // set total force to zero if (zeroflag) { fsum[0] = s_fsum.fx; fsum[1] = s_fsum.fy; fsum[2] = s_fsum.fz; MPI_Allreduce(fsum,fsumall,3,MPI_DOUBLE,MPI_SUM,world); h_fsumall(0) = fsumall[0]/count; h_fsumall(1) = fsumall[1]/count; h_fsumall(2) = fsumall[2]/count; k_fsumall.template modify(); k_fsumall.template sync(); // set total force zero in parallel on the device FixLangevinKokkosZeroForceFunctor zero_functor(this); Kokkos::parallel_for(nlocal,zero_functor); DeviceType::fence(); } // f is modified by both post_force and zero_force functors atomKK->modified(execution_space,datamask_modify); // thermostat omega and angmom // if (oflag) omega_thermostat(); // if (ascale) angmom_thermostat(); } /* ---------------------------------------------------------------------- */ template template KOKKOS_INLINE_FUNCTION FSUM FixLangevinKokkos::post_force_item(int i) const { FSUM fsum; double fdrag[3],fran[3]; double gamma1,gamma2; double fswap; double tsqrt_t = tsqrt; if (mask[i] & groupbit) { rand_type rand_gen = rand_pool.get_state(); if(Tp_TSTYLEATOM) tsqrt_t = sqrt(d_tforce[i]); if(Tp_RMASS){ gamma1 = -rmass[i] / t_period / ftm2v; gamma2 = sqrt(rmass[i]) * fran_prop_const / ftm2v; gamma1 *= 1.0/d_ratio[type[i]]; gamma2 *= 1.0/sqrt(d_ratio[type[i]]) * tsqrt_t; } else { gamma1 = d_gfactor1[type[i]]; gamma2 = d_gfactor2[type[i]] * tsqrt_t; } fran[0] = gamma2 * (rand_gen.drand() - 0.5); //(random->uniform()-0.5); fran[1] = gamma2 * (rand_gen.drand() - 0.5); //(random->uniform()-0.5); fran[2] = gamma2 * (rand_gen.drand() - 0.5); //(random->uniform()-0.5); if(Tp_BIAS){ fdrag[0] = gamma1*v(i,0); fdrag[1] = gamma1*v(i,1); fdrag[2] = gamma1*v(i,2); if (v(i,0) == 0.0) fran[0] = 0.0; if (v(i,1) == 0.0) fran[1] = 0.0; if (v(i,2) == 0.0) fran[2] = 0.0; }else{ fdrag[0] = gamma1*v(i,0); fdrag[1] = gamma1*v(i,1); fdrag[2] = gamma1*v(i,2); } if (Tp_GJF) { fswap = 0.5*(fran[0]+d_franprev(i,0)); d_franprev(i,0) = fran[0]; fran[0] = fswap; fswap = 0.5*(fran[1]+d_franprev(i,1)); d_franprev(i,1) = fran[1]; fran[1] = fswap; fswap = 0.5*(fran[2]+d_franprev(i,2)); d_franprev(i,2) = fran[2]; fran[2] = fswap; fdrag[0] *= gjffac; fdrag[1] *= gjffac; fdrag[2] *= gjffac; fran[0] *= gjffac; fran[1] *= gjffac; fran[2] *= gjffac; f(i,0) *= gjffac; f(i,1) *= gjffac; f(i,2) *= gjffac; } f(i,0) += fdrag[0] + fran[0]; f(i,1) += fdrag[1] + fran[1]; f(i,2) += fdrag[2] + fran[2]; if (Tp_TALLY) { d_flangevin(i,0) = fdrag[0] + fran[0]; d_flangevin(i,1) = fdrag[1] + fran[1]; d_flangevin(i,2) = fdrag[2] + fran[2]; } if (Tp_ZERO) { fsum.fx = fran[0]; fsum.fy = fran[1]; fsum.fz = fran[2]; } rand_pool.free_state(rand_gen); } return fsum; } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION void FixLangevinKokkos::zero_force_item(int i) const { if (mask[i] & groupbit) { f(i,0) -= d_fsumall[0]; f(i,1) -= d_fsumall[1]; f(i,2) -= d_fsumall[2]; } } /* ---------------------------------------------------------------------- set current t_target and t_sqrt ------------------------------------------------------------------------- */ template void FixLangevinKokkos::compute_target() { atomKK->sync(Host, MASK_MASK); mask = atomKK->k_mask.template view(); int nlocal = atomKK->nlocal; double delta = update->ntimestep - update->beginstep; if (delta != 0.0) delta /= update->endstep - update->beginstep; // if variable temp, evaluate variable, wrap with clear/add // reallocate tforce array if necessary if (tstyle == CONSTANT) { t_target = t_start + delta * (t_stop-t_start); tsqrt = sqrt(t_target); } else { modify->clearstep_compute(); if (tstyle == EQUAL) { t_target = input->variable->compute_equal(tvar); if (t_target < 0.0) error->one(FLERR,"Fix langevin variable returned negative temperature"); tsqrt = sqrt(t_target); } else { if (atom->nmax > maxatom2) { maxatom2 = atom->nmax; memory->destroy_kokkos(k_tforce,tforce); memory->create_kokkos(k_tforce,tforce,maxatom2,"langevin:tforce"); d_tforce = k_tforce.template view(); h_tforce = k_tforce.template view(); } input->variable->compute_atom(tvar,igroup,tforce,1,0); // tforce is modified on host k_tforce.template modify(); for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) if (h_tforce[i] < 0.0) error->one(FLERR, "Fix langevin variable returned negative temperature"); } modify->addstep_compute(update->ntimestep + 1); } } /* ---------------------------------------------------------------------- */ template void FixLangevinKokkos::reset_dt() { if (atomKK->mass) { for (int i = 1; i <= atomKK->ntypes; i++) { h_gfactor2[i] = sqrt(atomKK->mass[i]) * sqrt(24.0*force->boltz/t_period/update->dt/force->mvv2e) / force->ftm2v; h_gfactor2[i] *= 1.0/sqrt(h_ratio[i]); } k_gfactor2.template modify(); } } /* ---------------------------------------------------------------------- */ template double FixLangevinKokkos::compute_scalar() { if (!tallyflag || flangevin == NULL) return 0.0; v = atomKK->k_v.template view(); mask = atomKK->k_mask.template view(); // capture the very first energy transfer to thermal reservoir if (update->ntimestep == update->beginstep) { energy_onestep = 0.0; atomKK->sync(execution_space,V_MASK | MASK_MASK); int nlocal = atomKK->nlocal; k_flangevin.template sync(); FixLangevinKokkosTallyEnergyFunctor scalar_functor(this); Kokkos::parallel_reduce(nlocal,scalar_functor,energy_onestep); DeviceType::fence(); energy = 0.5*energy_onestep*update->dt; } // convert midstep energy back to previous fullstep energy double energy_me = energy - 0.5*energy_onestep*update->dt; double energy_all; MPI_Allreduce(&energy_me,&energy_all,1,MPI_DOUBLE,MPI_SUM,world); return -energy_all; } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION double FixLangevinKokkos::compute_energy_item(int i) const { double energy; if (mask[i] & groupbit) energy = d_flangevin(i,0)*v(i,0) + d_flangevin(i,1)*v(i,1) + d_flangevin(i,2)*v(i,2); return energy; } /* ---------------------------------------------------------------------- tally energy transfer to thermal reservoir ------------------------------------------------------------------------- */ template void FixLangevinKokkos::end_of_step() { if (!tallyflag) return; v = atomKK->k_v.template view(); mask = atomKK->k_mask.template view(); atomKK->sync(execution_space,V_MASK | MASK_MASK); int nlocal = atomKK->nlocal; energy_onestep = 0.0; k_flangevin.template sync(); FixLangevinKokkosTallyEnergyFunctor tally_functor(this); Kokkos::parallel_reduce(nlocal,tally_functor,energy_onestep); DeviceType::fence(); energy += energy_onestep*update->dt; } /* ---------------------------------------------------------------------- copy values within local atom-based array ------------------------------------------------------------------------- */ template void FixLangevinKokkos::copy_arrays(int i, int j, int delflag) { for (int m = 0; m < nvalues; m++) h_franprev(j,m) = h_franprev(i,m); k_franprev.template modify(); } /* ---------------------------------------------------------------------- */ template void FixLangevinKokkos::cleanup_copy() { random = NULL; tstr = NULL; gfactor1 = NULL; gfactor2 = NULL; ratio = NULL; id_temp = NULL; flangevin = NULL; tforce = NULL; gjfflag = 0; franprev = NULL; id = style = NULL; vatom = NULL; } namespace LAMMPS_NS { template class FixLangevinKokkos; #ifdef KOKKOS_HAVE_CUDA template class FixLangevinKokkos; #endif } diff --git a/src/KOKKOS/fix_nh_kokkos.cpp b/src/KOKKOS/fix_nh_kokkos.cpp index 8cc06fc52..2b5525936 100644 --- a/src/KOKKOS/fix_nh_kokkos.cpp +++ b/src/KOKKOS/fix_nh_kokkos.cpp @@ -1,740 +1,741 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Stan Moore (SNL) ------------------------------------------------------------------------- */ #include #include #include #include "fix_nh_kokkos.h" #include "math_extra.h" #include "atom.h" #include "force.h" #include "group.h" #include "comm.h" #include "neighbor.h" #include "irregular.h" #include "modify.h" #include "fix_deform.h" #include "compute.h" #include "kspace.h" #include "update.h" #include "respa.h" #include "domain_kokkos.h" #include "memory.h" #include "error.h" #include "atom_masks.h" #include "atom_kokkos.h" using namespace LAMMPS_NS; using namespace FixConst; #define DELTAFLIP 0.1 #define TILTMAX 1.5 enum{NOBIAS,BIAS}; enum{NONE,XYZ,XY,YZ,XZ}; enum{ISO,ANISO,TRICLINIC}; /* ---------------------------------------------------------------------- NVT,NPH,NPT integrators for improved Nose-Hoover equations of motion ---------------------------------------------------------------------- */ template FixNHKokkos::FixNHKokkos(LAMMPS *lmp, int narg, char **arg) : FixNH(lmp, narg, arg) { + kokkosable = 1; domainKK = (DomainKokkos *) domain; execution_space = ExecutionSpaceFromDevice::space; datamask_read = EMPTY_MASK; datamask_modify = EMPTY_MASK; } /* ---------------------------------------------------------------------- */ template FixNHKokkos::~FixNHKokkos() { } /* ---------------------------------------------------------------------- */ template void FixNHKokkos::init() { FixNH::init(); atomKK->k_mass.modify(); atomKK->k_mass.sync(); } /* ---------------------------------------------------------------------- compute T,P before integrator starts ------------------------------------------------------------------------- */ template void FixNHKokkos::setup(int vflag) { // t_target is needed by NPH and NPT in compute_scalar() // If no thermostat or using fix nphug, // t_target must be defined by other means. if (tstat_flag && strcmp(style,"nphug") != 0) { compute_temp_target(); } else if (pstat_flag) { // t0 = reference temperature for masses // cannot be done in init() b/c temperature cannot be called there // is b/c Modify::init() inits computes after fixes due to dof dependence // guesstimate a unit-dependent t0 if actual T = 0.0 // if it was read in from a restart file, leave it be if (t0 == 0.0) { atomKK->sync(temperature->execution_space,temperature->datamask_read); atomKK->modified(temperature->execution_space,temperature->datamask_modify); t0 = temperature->compute_scalar(); if (t0 == 0.0) { if (strcmp(update->unit_style,"lj") == 0) t0 = 1.0; else t0 = 300.0; } } t_target = t0; } if (pstat_flag) compute_press_target(); atomKK->sync(temperature->execution_space,temperature->datamask_read); atomKK->modified(temperature->execution_space,temperature->datamask_modify); t_current = temperature->compute_scalar(); tdof = temperature->dof; if (pstat_flag) { //atomKK->sync(pressure->execution_space,pressure->datamask_read); //atomKK->modified(pressure->execution_space,pressure->datamask_modify); if (pstyle == ISO) pressure->compute_scalar(); else pressure->compute_vector(); couple(); pressure->addstep(update->ntimestep+1); } // masses and initial forces on thermostat variables if (tstat_flag) { eta_mass[0] = tdof * boltz * t_target / (t_freq*t_freq); for (int ich = 1; ich < mtchain; ich++) eta_mass[ich] = boltz * t_target / (t_freq*t_freq); for (int ich = 1; ich < mtchain; ich++) { eta_dotdot[ich] = (eta_mass[ich-1]*eta_dot[ich-1]*eta_dot[ich-1] - boltz * t_target) / eta_mass[ich]; } } // masses and initial forces on barostat variables if (pstat_flag) { double kt = boltz * t_target; double nkt = atom->natoms * kt; for (int i = 0; i < 3; i++) if (p_flag[i]) omega_mass[i] = nkt/(p_freq[i]*p_freq[i]); if (pstyle == TRICLINIC) { for (int i = 3; i < 6; i++) if (p_flag[i]) omega_mass[i] = nkt/(p_freq[i]*p_freq[i]); } // masses and initial forces on barostat thermostat variables if (mpchain) { etap_mass[0] = boltz * t_target / (p_freq_max*p_freq_max); for (int ich = 1; ich < mpchain; ich++) etap_mass[ich] = boltz * t_target / (p_freq_max*p_freq_max); for (int ich = 1; ich < mpchain; ich++) etap_dotdot[ich] = (etap_mass[ich-1]*etap_dot[ich-1]*etap_dot[ich-1] - boltz * t_target) / etap_mass[ich]; } } } /* ---------------------------------------------------------------------- 1st half of Verlet update ------------------------------------------------------------------------- */ template void FixNHKokkos::initial_integrate(int vflag) { // update eta_press_dot if (pstat_flag && mpchain) nhc_press_integrate(); // update eta_dot if (tstat_flag) { compute_temp_target(); nhc_temp_integrate(); } // need to recompute pressure to account for change in KE // t_current is up-to-date, but compute_temperature is not // compute appropriately coupled elements of mvv_current if (pstat_flag) { atomKK->sync(temperature->execution_space,temperature->datamask_read); atomKK->modified(temperature->execution_space,temperature->datamask_modify); //atomKK->sync(pressure->execution_space,pressure->datamask_read); //atomKK->modified(pressure->execution_space,pressure->datamask_modify); if (pstyle == ISO) { temperature->compute_scalar(); pressure->compute_scalar(); } else { temperature->compute_vector(); pressure->compute_vector(); } couple(); pressure->addstep(update->ntimestep+1); } if (pstat_flag) { compute_press_target(); nh_omega_dot(); nh_v_press(); } nve_v(); // remap simulation box by 1/2 step if (pstat_flag) remap(); nve_x(); // remap simulation box by 1/2 step // redo KSpace coeffs since volume has changed if (pstat_flag) { remap(); if (kspace_flag) force->kspace->setup(); } } /* ---------------------------------------------------------------------- 2nd half of Verlet update ------------------------------------------------------------------------- */ template void FixNHKokkos::final_integrate() { nve_v(); // re-compute temp before nh_v_press() // only needed for temperature computes with BIAS on reneighboring steps: // b/c some biases store per-atom values (e.g. temp/profile) // per-atom values are invalid if reneigh/comm occurred // since temp->compute() in initial_integrate() if (which == BIAS && neighbor->ago == 0) atomKK->sync(temperature->execution_space,temperature->datamask_read); atomKK->modified(temperature->execution_space,temperature->datamask_modify); t_current = temperature->compute_scalar(); if (pstat_flag) nh_v_press(); // compute new T,P after velocities rescaled by nh_v_press() // compute appropriately coupled elements of mvv_current atomKK->sync(temperature->execution_space,temperature->datamask_read); atomKK->modified(temperature->execution_space,temperature->datamask_modify); t_current = temperature->compute_scalar(); tdof = temperature->dof; if (pstat_flag) { //atomKK->sync(pressure->execution_space,pressure->datamask_read); //atomKK->modified(pressure->execution_space,pressure->datamask_modify); if (pstyle == ISO) pressure->compute_scalar(); else pressure->compute_vector(); couple(); pressure->addstep(update->ntimestep+1); } if (pstat_flag) nh_omega_dot(); // update eta_dot // update eta_press_dot if (tstat_flag) nhc_temp_integrate(); if (pstat_flag && mpchain) nhc_press_integrate(); } /* ---------------------------------------------------------------------- change box size remap all atoms or dilate group atoms depending on allremap flag if rigid bodies exist, scale rigid body centers-of-mass ------------------------------------------------------------------------- */ template void FixNHKokkos::remap() { double oldlo,oldhi; double expfac; int nlocal = atom->nlocal; double *h = domain->h; // omega is not used, except for book-keeping for (int i = 0; i < 6; i++) omega[i] += dto*omega_dot[i]; // convert pertinent atoms and rigid bodies to lamda coords domainKK->x2lamda(nlocal); //if (allremap) domainKK->x2lamda(nlocal); //else { // for (i = 0; i < nlocal; i++) // if (mask[i] & dilate_group_bit) // domain->x2lamda(x[i],x[i]); //} if (nrigid) error->all(FLERR,"Cannot (yet) use rigid bodies with fix nh and Kokkos"); //for (i = 0; i < nrigid; i++) // modify->fix[rfix[i]]->deform(0); // reset global and local box to new size/shape // this operation corresponds to applying the // translate and scale operations // corresponding to the solution of the following ODE: // // h_dot = omega_dot * h // // where h_dot, omega_dot and h are all upper-triangular // 3x3 tensors. In Voigt notation, the elements of the // RHS product tensor are: // h_dot = [0*0, 1*1, 2*2, 1*3+3*2, 0*4+5*3+4*2, 0*5+5*1] // // Ordering of operations preserves time symmetry. double dto2 = dto/2.0; double dto4 = dto/4.0; double dto8 = dto/8.0; // off-diagonal components, first half if (pstyle == TRICLINIC) { if (p_flag[4]) { expfac = exp(dto8*omega_dot[0]); h[4] *= expfac; h[4] += dto4*(omega_dot[5]*h[3]+omega_dot[4]*h[2]); h[4] *= expfac; } if (p_flag[3]) { expfac = exp(dto4*omega_dot[1]); h[3] *= expfac; h[3] += dto2*(omega_dot[3]*h[2]); h[3] *= expfac; } if (p_flag[5]) { expfac = exp(dto4*omega_dot[0]); h[5] *= expfac; h[5] += dto2*(omega_dot[5]*h[1]); h[5] *= expfac; } if (p_flag[4]) { expfac = exp(dto8*omega_dot[0]); h[4] *= expfac; h[4] += dto4*(omega_dot[5]*h[3]+omega_dot[4]*h[2]); h[4] *= expfac; } } // scale diagonal components // scale tilt factors with cell, if set if (p_flag[0]) { oldlo = domain->boxlo[0]; oldhi = domain->boxhi[0]; expfac = exp(dto*omega_dot[0]); domain->boxlo[0] = (oldlo-fixedpoint[0])*expfac + fixedpoint[0]; domain->boxhi[0] = (oldhi-fixedpoint[0])*expfac + fixedpoint[0]; } if (p_flag[1]) { oldlo = domain->boxlo[1]; oldhi = domain->boxhi[1]; expfac = exp(dto*omega_dot[1]); domain->boxlo[1] = (oldlo-fixedpoint[1])*expfac + fixedpoint[1]; domain->boxhi[1] = (oldhi-fixedpoint[1])*expfac + fixedpoint[1]; if (scalexy) h[5] *= expfac; } if (p_flag[2]) { oldlo = domain->boxlo[2]; oldhi = domain->boxhi[2]; expfac = exp(dto*omega_dot[2]); domain->boxlo[2] = (oldlo-fixedpoint[2])*expfac + fixedpoint[2]; domain->boxhi[2] = (oldhi-fixedpoint[2])*expfac + fixedpoint[2]; if (scalexz) h[4] *= expfac; if (scaleyz) h[3] *= expfac; } // off-diagonal components, second half if (pstyle == TRICLINIC) { if (p_flag[4]) { expfac = exp(dto8*omega_dot[0]); h[4] *= expfac; h[4] += dto4*(omega_dot[5]*h[3]+omega_dot[4]*h[2]); h[4] *= expfac; } if (p_flag[3]) { expfac = exp(dto4*omega_dot[1]); h[3] *= expfac; h[3] += dto2*(omega_dot[3]*h[2]); h[3] *= expfac; } if (p_flag[5]) { expfac = exp(dto4*omega_dot[0]); h[5] *= expfac; h[5] += dto2*(omega_dot[5]*h[1]); h[5] *= expfac; } if (p_flag[4]) { expfac = exp(dto8*omega_dot[0]); h[4] *= expfac; h[4] += dto4*(omega_dot[5]*h[3]+omega_dot[4]*h[2]); h[4] *= expfac; } } domain->yz = h[3]; domain->xz = h[4]; domain->xy = h[5]; // tilt factor to cell length ratio can not exceed TILTMAX in one step if (domain->yz < -TILTMAX*domain->yprd || domain->yz > TILTMAX*domain->yprd || domain->xz < -TILTMAX*domain->xprd || domain->xz > TILTMAX*domain->xprd || domain->xy < -TILTMAX*domain->xprd || domain->xy > TILTMAX*domain->xprd) error->all(FLERR,"Fix npt/nph has tilted box too far in one step - " "periodic cell is too far from equilibrium state"); domain->set_global_box(); domain->set_local_box(); // convert pertinent atoms and rigid bodies back to box coords domainKK->lamda2x(nlocal); //if (allremap) domainKK->lamda2x(nlocal); //else { // for (i = 0; i < nlocal; i++) // if (mask[i] & dilate_group_bit) // domain->lamda2x(x[i],x[i]); //} //if (nrigid) // for (i = 0; i < nrigid; i++) // modify->fix[rfix[i]]->deform(1); } /* ---------------------------------------------------------------------- perform half-step barostat scaling of velocities -----------------------------------------------------------------------*/ template void FixNHKokkos::nh_v_press() { atomKK->sync(execution_space,V_MASK | MASK_MASK); v = atomKK->k_v.view(); mask = atomKK->k_mask.view(); int nlocal = atomKK->nlocal; if (igroup == atomKK->firstgroup) nlocal = atomKK->nfirst; factor[0] = exp(-dt4*(omega_dot[0]+mtk_term2)); factor[1] = exp(-dt4*(omega_dot[1]+mtk_term2)); factor[2] = exp(-dt4*(omega_dot[2]+mtk_term2)); if (which == BIAS) { atomKK->sync(temperature->execution_space,temperature->datamask_read); temperature->remove_bias_all(); atomKK->modified(temperature->execution_space,temperature->datamask_modify); } copymode = 1; if (pstyle == TRICLINIC) Kokkos::parallel_for(Kokkos::RangePolicy >(0,nlocal),*this); else Kokkos::parallel_for(Kokkos::RangePolicy >(0,nlocal),*this); DeviceType::fence(); copymode = 0; atomKK->modified(execution_space,V_MASK); if (which == BIAS) { atomKK->sync(temperature->execution_space,temperature->datamask_read); temperature->restore_bias_all(); atomKK->modified(temperature->execution_space,temperature->datamask_modify); } } template template KOKKOS_INLINE_FUNCTION void FixNHKokkos::operator()(TagFixNH_nh_v_press, const int &i) const { if (mask[i] & groupbit) { v(i,0) *= factor[0]; v(i,1) *= factor[1]; v(i,2) *= factor[2]; if (TRICLINIC_FLAG) { v(i,0) += -dthalf*(v(i,1)*omega_dot[5] + v(i,2)*omega_dot[4]); v(i,1) += -dthalf*v(i,2)*omega_dot[3]; } v(i,0) *= factor[0]; v(i,1) *= factor[1]; v(i,2) *= factor[2]; } } /* ---------------------------------------------------------------------- perform half-step update of velocities -----------------------------------------------------------------------*/ template void FixNHKokkos::nve_v() { atomKK->sync(execution_space,X_MASK | V_MASK | F_MASK | MASK_MASK | RMASS_MASK | TYPE_MASK); atomKK->modified(execution_space,V_MASK); v = atomKK->k_v.view(); f = atomKK->k_f.view(); rmass = atomKK->rmass; mass = atomKK->k_mass.view(); type = atomKK->k_type.view(); mask = atomKK->k_mask.view(); int nlocal = atomKK->nlocal; if (igroup == atomKK->firstgroup) nlocal = atomKK->nfirst; copymode = 1; if (rmass) Kokkos::parallel_for(Kokkos::RangePolicy >(0,nlocal),*this); else Kokkos::parallel_for(Kokkos::RangePolicy >(0,nlocal),*this); DeviceType::fence(); copymode = 0; } template template KOKKOS_INLINE_FUNCTION void FixNHKokkos::operator()(TagFixNH_nve_v, const int &i) const { if (RMASS) { if (mask[i] & groupbit) { const F_FLOAT dtfm = dtf / rmass[i]; v(i,0) += dtfm*f(i,0); v(i,1) += dtfm*f(i,1); v(i,2) += dtfm*f(i,2); } } else { if (mask[i] & groupbit) { const F_FLOAT dtfm = dtf / mass[type[i]]; v(i,0) += dtfm*f(i,0); v(i,1) += dtfm*f(i,1); v(i,2) += dtfm*f(i,2); } } } /* ---------------------------------------------------------------------- perform full-step update of positions -----------------------------------------------------------------------*/ template void FixNHKokkos::nve_x() { atomKK->sync(execution_space,X_MASK | V_MASK | MASK_MASK); atomKK->modified(execution_space,X_MASK); x = atomKK->k_x.view(); v = atomKK->k_v.view(); mask = atomKK->k_mask.view(); int nlocal = atomKK->nlocal; if (igroup == atomKK->firstgroup) nlocal = atomKK->nfirst; // x update by full step only for atoms in group copymode = 1; Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); DeviceType::fence(); copymode = 0; } template KOKKOS_INLINE_FUNCTION void FixNHKokkos::operator()(TagFixNH_nve_x, const int &i) const { if (mask[i] & groupbit) { x(i,0) += dtv * v(i,0); x(i,1) += dtv * v(i,1); x(i,2) += dtv * v(i,2); } } /* ---------------------------------------------------------------------- perform half-step thermostat scaling of velocities -----------------------------------------------------------------------*/ template void FixNHKokkos::nh_v_temp() { atomKK->sync(execution_space,V_MASK | MASK_MASK); v = atomKK->k_v.view(); mask = atomKK->k_mask.view(); int nlocal = atomKK->nlocal; if (igroup == atomKK->firstgroup) nlocal = atomKK->nfirst; if (which == BIAS) { atomKK->sync(temperature->execution_space,temperature->datamask_read); temperature->remove_bias_all(); atomKK->modified(temperature->execution_space,temperature->datamask_modify); } copymode = 1; Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); DeviceType::fence(); copymode = 0; atomKK->modified(execution_space,V_MASK); if (which == BIAS) { atomKK->sync(temperature->execution_space,temperature->datamask_read); temperature->restore_bias_all(); atomKK->modified(temperature->execution_space,temperature->datamask_modify); } } template KOKKOS_INLINE_FUNCTION void FixNHKokkos::operator()(TagFixNH_nh_v_temp, const int &i) const { if (mask[i] & groupbit) { v(i,0) *= factor_eta; v(i,1) *= factor_eta; v(i,2) *= factor_eta; } } /* ---------------------------------------------------------------------- if any tilt ratios exceed limits, set flip = 1 and compute new tilt values do not flip in x or y if non-periodic (can tilt but not flip) this is b/c the box length would be changed (dramatically) by flip if yz tilt exceeded, adjust C vector by one B vector if xz tilt exceeded, adjust C vector by one A vector if xy tilt exceeded, adjust B vector by one A vector check yz first since it may change xz, then xz check comes after if any flip occurs, create new box in domain image_flip() adjusts image flags due to box shape change induced by flip remap() puts atoms outside the new box back into the new box perform irregular on atoms in lamda coords to migrate atoms to new procs important that image_flip comes before remap, since remap may change image flags to new values, making eqs in doc of Domain:image_flip incorrect ------------------------------------------------------------------------- */ template void FixNHKokkos::pre_exchange() { double xprd = domain->xprd; double yprd = domain->yprd; // flip is only triggered when tilt exceeds 0.5 by DELTAFLIP // this avoids immediate re-flipping due to tilt oscillations double xtiltmax = (0.5+DELTAFLIP)*xprd; double ytiltmax = (0.5+DELTAFLIP)*yprd; int flipxy,flipxz,flipyz; flipxy = flipxz = flipyz = 0; if (domain->yperiodic) { if (domain->yz < -ytiltmax) { domain->yz += yprd; domain->xz += domain->xy; flipyz = 1; } else if (domain->yz >= ytiltmax) { domain->yz -= yprd; domain->xz -= domain->xy; flipyz = -1; } } if (domain->xperiodic) { if (domain->xz < -xtiltmax) { domain->xz += xprd; flipxz = 1; } else if (domain->xz >= xtiltmax) { domain->xz -= xprd; flipxz = -1; } if (domain->xy < -xtiltmax) { domain->xy += xprd; flipxy = 1; } else if (domain->xy >= xtiltmax) { domain->xy -= xprd; flipxy = -1; } } int flip = 0; if (flipxy || flipxz || flipyz) flip = 1; if (flip) { domain->set_global_box(); domain->set_local_box(); domainKK->image_flip(flipxy,flipxz,flipyz); domainKK->remap_all(); domainKK->x2lamda(atom->nlocal); atomKK->sync(Host,ALL_MASK); irregular->migrate_atoms(); atomKK->modified(Host,ALL_MASK); domainKK->lamda2x(atom->nlocal); } } namespace LAMMPS_NS { template class FixNHKokkos; #ifdef KOKKOS_HAVE_CUDA template class FixNHKokkos; #endif } diff --git a/src/KOKKOS/fix_nph_kokkos.cpp b/src/KOKKOS/fix_nph_kokkos.cpp index f3f7c271d..34fc212c0 100644 --- a/src/KOKKOS/fix_nph_kokkos.cpp +++ b/src/KOKKOS/fix_nph_kokkos.cpp @@ -1,77 +1,78 @@ /* ---------------------------------------------------------------------- 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 #include "fix_nph_kokkos.h" #include "modify.h" #include "error.h" using namespace LAMMPS_NS; using namespace FixConst; /* ---------------------------------------------------------------------- */ template FixNPHKokkos::FixNPHKokkos(LAMMPS *lmp, int narg, char **arg) : FixNHKokkos(lmp, narg, arg) { + this->kokkosable = 1; if (this->tstat_flag) this->error->all(FLERR,"Temperature control can not be used with fix nph"); if (!this->pstat_flag) this->error->all(FLERR,"Pressure control must be used with fix nph"); // create a new compute temp style // id = fix-ID + temp // compute group = all since pressure is always global (group all) // and thus its KE/temperature contribution should use group all int n = strlen(this->id) + 6; this->id_temp = new char[n]; strcpy(this->id_temp,this->id); strcat(this->id_temp,"_temp"); char **newarg = new char*[3]; newarg[0] = this->id_temp; newarg[1] = (char *) "all"; newarg[2] = (char *) "temp/kk"; this->modify->add_compute(3,newarg); delete [] newarg; this->tcomputeflag = 1; // create a new compute pressure style // id = fix-ID + press, compute group = all // pass id_temp as 4th arg to pressure constructor n = strlen(this->id) + 7; this->id_press = new char[n]; strcpy(this->id_press,this->id); strcat(this->id_press,"_press"); newarg = new char*[4]; newarg[0] = this->id_press; newarg[1] = (char *) "all"; newarg[2] = (char *) "pressure"; newarg[3] = this->id_temp; this->modify->add_compute(4,newarg); delete [] newarg; this->pcomputeflag = 1; } namespace LAMMPS_NS { template class FixNPHKokkos; #ifdef KOKKOS_HAVE_CUDA template class FixNPHKokkos; #endif } diff --git a/src/KOKKOS/fix_npt_kokkos.cpp b/src/KOKKOS/fix_npt_kokkos.cpp index bbc26b8e8..c99a322a0 100644 --- a/src/KOKKOS/fix_npt_kokkos.cpp +++ b/src/KOKKOS/fix_npt_kokkos.cpp @@ -1,77 +1,78 @@ /* ---------------------------------------------------------------------- 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 #include "fix_npt_kokkos.h" #include "modify.h" #include "error.h" using namespace LAMMPS_NS; using namespace FixConst; /* ---------------------------------------------------------------------- */ template FixNPTKokkos::FixNPTKokkos(LAMMPS *lmp, int narg, char **arg) : FixNHKokkos(lmp, narg, arg) { + this->kokkosable = 1; if (!this->tstat_flag) this->error->all(FLERR,"Temperature control must be used with fix npt"); if (!this->pstat_flag) this->error->all(FLERR,"Pressure control must be used with fix npt"); // create a new compute temp style // id = fix-ID + temp // compute group = all since pressure is always global (group all) // and thus its KE/temperature contribution should use group all int n = strlen(this->id) + 6; this->id_temp = new char[n]; strcpy(this->id_temp,this->id); strcat(this->id_temp,"_temp"); char **newarg = new char*[3]; newarg[0] = this->id_temp; newarg[1] = (char *) "all"; newarg[2] = (char *) "temp/kk"; this->modify->add_compute(3,newarg); delete [] newarg; this->tcomputeflag = 1; // create a new compute pressure style // id = fix-ID + press, compute group = all // pass id_temp as 4th arg to pressure constructor n = strlen(this->id) + 7; this->id_press = new char[n]; strcpy(this->id_press,this->id); strcat(this->id_press,"_press"); newarg = new char*[4]; newarg[0] = this->id_press; newarg[1] = (char *) "all"; newarg[2] = (char *) "pressure"; newarg[3] = this->id_temp; this->modify->add_compute(4,newarg); delete [] newarg; this->pcomputeflag = 1; } namespace LAMMPS_NS { template class FixNPTKokkos; #ifdef KOKKOS_HAVE_CUDA template class FixNPTKokkos; #endif } diff --git a/src/KOKKOS/fix_nve_kokkos.cpp b/src/KOKKOS/fix_nve_kokkos.cpp index 5e7e9b529..4c041f85b 100644 --- a/src/KOKKOS/fix_nve_kokkos.cpp +++ b/src/KOKKOS/fix_nve_kokkos.cpp @@ -1,180 +1,181 @@ /* ---------------------------------------------------------------------- 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 #include #include "fix_nve_kokkos.h" #include "atom_masks.h" #include "atom_kokkos.h" #include "force.h" #include "update.h" #include "respa.h" #include "error.h" using namespace LAMMPS_NS; using namespace FixConst; /* ---------------------------------------------------------------------- */ template FixNVEKokkos::FixNVEKokkos(LAMMPS *lmp, int narg, char **arg) : FixNVE(lmp, narg, arg) { + kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; datamask_read = X_MASK | V_MASK | F_MASK | MASK_MASK | RMASS_MASK | TYPE_MASK; datamask_modify = X_MASK | V_MASK; } /* ---------------------------------------------------------------------- */ template void FixNVEKokkos::init() { FixNVE::init(); atomKK->k_mass.modify(); atomKK->k_mass.sync(); } /* ---------------------------------------------------------------------- allow for both per-type and per-atom mass ------------------------------------------------------------------------- */ template void FixNVEKokkos::initial_integrate(int vflag) { atomKK->sync(execution_space,datamask_read); atomKK->modified(execution_space,datamask_modify); x = atomKK->k_x.view(); v = atomKK->k_v.view(); f = atomKK->k_f.view(); rmass = atomKK->rmass; mass = atomKK->k_mass.view(); type = atomKK->k_type.view(); mask = atomKK->k_mask.view(); int nlocal = atomKK->nlocal; if (igroup == atomKK->firstgroup) nlocal = atomKK->nfirst; if (rmass) { FixNVEKokkosInitialIntegrateFunctor functor(this); Kokkos::parallel_for(nlocal,functor); } else { FixNVEKokkosInitialIntegrateFunctor functor(this); Kokkos::parallel_for(nlocal,functor); } DeviceType::fence(); } template KOKKOS_INLINE_FUNCTION void FixNVEKokkos::initial_integrate_item(int i) const { if (mask[i] & groupbit) { const double dtfm = dtf / mass[type[i]]; v(i,0) += dtfm * f(i,0); v(i,1) += dtfm * f(i,1); v(i,2) += dtfm * f(i,2); x(i,0) += dtv * v(i,0); x(i,1) += dtv * v(i,1); x(i,2) += dtv * v(i,2); } } template KOKKOS_INLINE_FUNCTION void FixNVEKokkos::initial_integrate_rmass_item(int i) const { if (mask[i] & groupbit) { const double dtfm = dtf / rmass[type[i]]; v(i,0) += dtfm * f(i,0); v(i,1) += dtfm * f(i,1); v(i,2) += dtfm * f(i,2); x(i,0) += dtv * v(i,0); x(i,1) += dtv * v(i,1); x(i,2) += dtv * v(i,2); } } /* ---------------------------------------------------------------------- */ template void FixNVEKokkos::final_integrate() { atomKK->sync(execution_space,datamask_read); atomKK->modified(execution_space,datamask_modify); v = atomKK->k_v.view(); f = atomKK->k_f.view(); rmass = atomKK->rmass; mass = atomKK->k_mass.view(); type = atomKK->k_type.view(); mask = atomKK->k_mask.view(); int nlocal = atomKK->nlocal; if (igroup == atomKK->firstgroup) nlocal = atomKK->nfirst; if (rmass) { FixNVEKokkosFinalIntegrateFunctor functor(this); Kokkos::parallel_for(nlocal,functor); } else { FixNVEKokkosFinalIntegrateFunctor functor(this); Kokkos::parallel_for(nlocal,functor); } DeviceType::fence(); // debug //atomKK->sync(Host,datamask_read); } template KOKKOS_INLINE_FUNCTION void FixNVEKokkos::final_integrate_item(int i) const { if (mask[i] & groupbit) { const double dtfm = dtf / mass[type[i]]; v(i,0) += dtfm * f(i,0); v(i,1) += dtfm * f(i,1); v(i,2) += dtfm * f(i,2); } } template KOKKOS_INLINE_FUNCTION void FixNVEKokkos::final_integrate_rmass_item(int i) const { if (mask[i] & groupbit) { const double dtfm = dtf / rmass[type[i]]; v(i,0) += dtfm * f(i,0); v(i,1) += dtfm * f(i,1); v(i,2) += dtfm * f(i,2); } } /* ---------------------------------------------------------------------- */ template void FixNVEKokkos::cleanup_copy() { id = style = NULL; vatom = NULL; } namespace LAMMPS_NS { template class FixNVEKokkos; #ifdef KOKKOS_HAVE_CUDA template class FixNVEKokkos; #endif } diff --git a/src/KOKKOS/fix_nvt_kokkos.cpp b/src/KOKKOS/fix_nvt_kokkos.cpp index c479251c3..9628ff023 100644 --- a/src/KOKKOS/fix_nvt_kokkos.cpp +++ b/src/KOKKOS/fix_nvt_kokkos.cpp @@ -1,58 +1,59 @@ /* ---------------------------------------------------------------------- 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 #include "fix_nvt_kokkos.h" #include "group.h" #include "modify.h" #include "error.h" using namespace LAMMPS_NS; using namespace FixConst; /* ---------------------------------------------------------------------- */ template FixNVTKokkos::FixNVTKokkos(LAMMPS *lmp, int narg, char **arg) : FixNHKokkos(lmp, narg, arg) { + this->kokkosable = 1; if (!this->tstat_flag) this->error->all(FLERR,"Temperature control must be used with fix nvt"); if (this->pstat_flag) this->error->all(FLERR,"Pressure control can not be used with fix nvt"); // create a new compute temp style // id = fix-ID + temp int n = strlen(this->id) + 6; this->id_temp = new char[n]; strcpy(this->id_temp,this->id); strcat(this->id_temp,"_temp"); char **newarg = new char*[3]; newarg[0] = this->id_temp; newarg[1] = this->group->names[this->igroup]; newarg[2] = (char *) "temp/kk"; this->modify->add_compute(3,newarg); delete [] newarg; this->tcomputeflag = 1; } namespace LAMMPS_NS { template class FixNVTKokkos; #ifdef KOKKOS_HAVE_CUDA template class FixNVTKokkos; #endif } diff --git a/src/KOKKOS/fix_qeq_reax_kokkos.cpp b/src/KOKKOS/fix_qeq_reax_kokkos.cpp index 8ae132e57..e54be7412 100644 --- a/src/KOKKOS/fix_qeq_reax_kokkos.cpp +++ b/src/KOKKOS/fix_qeq_reax_kokkos.cpp @@ -1,1232 +1,1233 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Ray Shan (SNL), Stan Moore (SNL) ------------------------------------------------------------------------- */ #include #include #include #include #include "fix_qeq_reax_kokkos.h" #include "kokkos.h" #include "atom.h" #include "atom_masks.h" #include "atom_kokkos.h" #include "comm.h" #include "force.h" #include "group.h" #include "modify.h" #include "neighbor.h" #include "neigh_list_kokkos.h" #include "neigh_request.h" #include "update.h" #include "integrate.h" #include "respa.h" #include "math_const.h" #include "memory.h" #include "error.h" #include "pair_kokkos.h" using namespace LAMMPS_NS; using namespace FixConst; #define SMALL 0.0001 #define EV_TO_KCAL_PER_MOL 14.4 #define TEAMSIZE 128 /* ---------------------------------------------------------------------- */ template FixQEqReaxKokkos::FixQEqReaxKokkos(LAMMPS *lmp, int narg, char **arg) : FixQEqReax(lmp, narg, arg) { + kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; datamask_read = X_MASK | V_MASK | F_MASK | MASK_MASK | Q_MASK | TYPE_MASK; datamask_modify = Q_MASK | X_MASK; nmax = nmax = m_cap = 0; allocated_flag = 0; } /* ---------------------------------------------------------------------- */ template FixQEqReaxKokkos::~FixQEqReaxKokkos() { if (copymode) return; } /* ---------------------------------------------------------------------- */ template void FixQEqReaxKokkos::init() { atomKK->k_q.modify(); atomKK->k_q.sync(); FixQEqReax::init(); neighflag = lmp->kokkos->neighflag; int irequest = neighbor->nrequest - 1; neighbor->requests[irequest]-> kokkos_host = Kokkos::Impl::is_same::value && !Kokkos::Impl::is_same::value; neighbor->requests[irequest]-> kokkos_device = Kokkos::Impl::is_same::value; if (neighflag == FULL) { neighbor->requests[irequest]->fix = 1; neighbor->requests[irequest]->pair = 0; neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; neighbor->requests[irequest]->full_cluster = 0; } else { //if (neighflag == HALF || neighflag == HALFTHREAD) neighbor->requests[irequest]->fix = 1; neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; neighbor->requests[irequest]->full_cluster = 0; neighbor->requests[irequest]->ghost = 1; } int ntypes = atom->ntypes; k_params = Kokkos::DualView ("FixQEqReax::params",ntypes+1); params = k_params.template view(); for (n = 1; n <= ntypes; n++) { k_params.h_view(n).chi = chi[n]; k_params.h_view(n).eta = eta[n]; k_params.h_view(n).gamma = gamma[n]; } k_params.template modify(); cutsq = swb * swb; init_shielding_k(); init_hist(); } /* ---------------------------------------------------------------------- */ template void FixQEqReaxKokkos::init_shielding_k() { int i,j; int ntypes = atom->ntypes; k_shield = DAT::tdual_ffloat_2d("qeq/kk:shield",ntypes+1,ntypes+1); d_shield = k_shield.template view(); for( i = 1; i <= ntypes; ++i ) for( j = 1; j <= ntypes; ++j ) k_shield.h_view(i,j) = pow( gamma[i] * gamma[j], -1.5 ); k_shield.template modify(); k_shield.template sync(); k_tap = DAT::tdual_ffloat_1d("qeq/kk:tap",8); d_tap = k_tap.template view(); for (i = 0; i < 8; i ++) k_tap.h_view(i) = Tap[i]; k_tap.template modify(); k_tap.template sync(); } /* ---------------------------------------------------------------------- */ template void FixQEqReaxKokkos::init_hist() { int i,j; k_s_hist = DAT::tdual_ffloat_2d("qeq/kk:s_hist",atom->nmax,5); d_s_hist = k_s_hist.template view(); h_s_hist = k_s_hist.h_view; k_t_hist = DAT::tdual_ffloat_2d("qeq/kk:t_hist",atom->nmax,5); d_t_hist = k_t_hist.template view(); h_t_hist = k_t_hist.h_view; for( i = 0; i < atom->nmax; i++ ) for( j = 0; j < 5; j++ ) k_s_hist.h_view(i,j) = k_t_hist.h_view(i,j) = 0.0; k_s_hist.template modify(); k_s_hist.template sync(); k_t_hist.template modify(); k_t_hist.template sync(); } /* ---------------------------------------------------------------------- */ template void FixQEqReaxKokkos::setup_pre_force(int vflag) { //neighbor->build_one(list); pre_force(vflag); } /* ---------------------------------------------------------------------- */ template void FixQEqReaxKokkos::pre_force(int vflag) { if (update->ntimestep % nevery) return; atomKK->sync(execution_space,datamask_read); atomKK->modified(execution_space,datamask_modify); x = atomKK->k_x.view(); v = atomKK->k_v.view(); f = atomKK->k_f.view(); q = atomKK->k_q.view(); tag = atomKK->k_tag.view(); type = atomKK->k_type.view(); mask = atomKK->k_mask.view(); nlocal = atomKK->nlocal; nall = atom->nlocal + atom->nghost; newton_pair = force->newton_pair; k_params.template sync(); k_shield.template sync(); k_tap.template sync(); NeighListKokkos* k_list = static_cast*>(list); d_numneigh = k_list->d_numneigh; d_neighbors = k_list->d_neighbors; d_ilist = k_list->d_ilist; inum = list->inum; k_list->clean_copy(); //cleanup_copy(); copymode = 1; int teamsize = TEAMSIZE; // allocate allocate_array(); // get max number of neighbor if (!allocated_flag || update->ntimestep == neighbor->lastcall) allocate_matrix(); // compute_H FixQEqReaxKokkosComputeHFunctor computeH_functor(this); Kokkos::parallel_scan(inum,computeH_functor); DeviceType::fence(); // init_matvec FixQEqReaxKokkosMatVecFunctor matvec_functor(this); Kokkos::parallel_for(inum,matvec_functor); DeviceType::fence(); // comm->forward_comm_fix(this); //Dist_vector( s ); pack_flag = 2; k_s.template modify(); k_s.template sync(); comm->forward_comm_fix(this); k_s.template modify(); k_s.template sync(); // comm->forward_comm_fix(this); //Dist_vector( t ); pack_flag = 3; k_t.template modify(); k_t.template sync(); comm->forward_comm_fix(this); k_t.template modify(); k_t.template sync(); // 1st cg solve over b_s, s cg_solve1(); DeviceType::fence(); // 2nd cg solve over b_t, t cg_solve2(); DeviceType::fence(); // calculate_Q(); calculate_q(); DeviceType::fence(); copymode = 0; if (!allocated_flag) allocated_flag = 1; } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION void FixQEqReaxKokkos::num_neigh_item(int ii, int &maxneigh) const { const int i = d_ilist[ii]; maxneigh += d_numneigh[i]; } /* ---------------------------------------------------------------------- */ template void FixQEqReaxKokkos::allocate_matrix() { int i,ii,m; const int inum = list->inum; nmax = atom->nmax; // determine the total space for the H matrix m_cap = 0; FixQEqReaxKokkosNumNeighFunctor neigh_functor(this); Kokkos::parallel_reduce(inum,neigh_functor,m_cap); d_firstnbr = typename AT::t_int_1d("qeq/kk:firstnbr",nmax); d_numnbrs = typename AT::t_int_1d("qeq/kk:numnbrs",nmax); d_jlist = typename AT::t_int_1d("qeq/kk:jlist",m_cap); d_val = typename AT::t_ffloat_1d("qeq/kk:val",m_cap); } /* ---------------------------------------------------------------------- */ template void FixQEqReaxKokkos::allocate_array() { if (atom->nmax > nmax) { nmax = atom->nmax; k_o = DAT::tdual_ffloat_1d("qeq/kk:h_o",nmax); d_o = k_o.template view(); h_o = k_o.h_view; d_Hdia_inv = typename AT::t_ffloat_1d("qeq/kk:h_Hdia_inv",nmax); d_b_s = typename AT::t_ffloat_1d("qeq/kk:h_b_s",nmax); d_b_t = typename AT::t_ffloat_1d("qeq/kk:h_b_t",nmax); k_s = DAT::tdual_ffloat_1d("qeq/kk:h_s",nmax); d_s = k_s.template view(); h_s = k_s.h_view; k_t = DAT::tdual_ffloat_1d("qeq/kk:h_t",nmax); d_t = k_t.template view(); h_t = k_t.h_view; d_p = typename AT::t_ffloat_1d("qeq/kk:h_p",nmax); d_r = typename AT::t_ffloat_1d("qeq/kk:h_r",nmax); k_d = DAT::tdual_ffloat_1d("qeq/kk:h_d",nmax); d_d = k_d.template view(); h_d = k_d.h_view; k_s_hist = DAT::tdual_ffloat_2d("qeq/kk:s_hist",nmax,5); d_s_hist = k_s_hist.template view(); h_s_hist = k_s_hist.h_view; k_t_hist = DAT::tdual_ffloat_2d("qeq/kk:t_hist",nmax,5); d_t_hist = k_t_hist.template view(); h_t_hist = k_t_hist.h_view; } // init_storage const int ignum = atom->nlocal + atom->nghost; FixQEqReaxKokkosZeroFunctor zero_functor(this); Kokkos::parallel_for(ignum,zero_functor); DeviceType::fence(); } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION void FixQEqReaxKokkos::zero_item(int ii) const { const int i = d_ilist[ii]; const int itype = type(i); if (mask[i] & groupbit) { d_Hdia_inv[i] = 1.0 / params(itype).eta; d_b_s[i] = -params(itype).chi; d_b_t[i] = -1.0; d_s[i] = 0.0; d_t[i] = 0.0; d_p[i] = 0.0; d_o[i] = 0.0; d_r[i] = 0.0; d_d[i] = 0.0; //for( int j = 0; j < 5; j++ ) //d_s_hist(i,j) = d_t_hist(i,j) = 0.0; } } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION void FixQEqReaxKokkos::compute_h_item(int ii, int &m_fill, const bool &final) const { const int i = d_ilist[ii]; int j,jj,jtag,jtype,flag; if (mask[i] & groupbit) { const X_FLOAT xtmp = x(i,0); const X_FLOAT ytmp = x(i,1); const X_FLOAT ztmp = x(i,2); const int itype = type(i); const int itag = tag(i); const int jnum = d_numneigh[i]; if (final) d_firstnbr[i] = m_fill; for (jj = 0; jj < jnum; jj++) { j = d_neighbors(i,jj); j &= NEIGHMASK; jtype = type(j); const X_FLOAT delx = x(j,0) - xtmp; const X_FLOAT dely = x(j,1) - ytmp; const X_FLOAT delz = x(j,2) - ztmp; if (neighflag != FULL) { flag = 0; if (j < nlocal) flag = 1; else if (tag[i] < tag[j]) flag = 1; else if (tag[i] == tag[j]) { if (delz > SMALL) flag = 1; else if (fabs(delz) < SMALL) { if (dely > SMALL) flag = 1; else if (fabs(dely) < SMALL && delx > SMALL) flag = 1; } } if (!flag) continue; } const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; if (rsq > cutsq) continue; const F_FLOAT r = sqrt(rsq); if (final) { d_jlist(m_fill) = j; const F_FLOAT shldij = d_shield(itype,jtype); d_val(m_fill) = calculate_H_k(r,shldij); } m_fill++; } if (final) d_numnbrs[i] = m_fill - d_firstnbr[i]; } } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION double FixQEqReaxKokkos::calculate_H_k(const F_FLOAT &r, const F_FLOAT &shld) const { F_FLOAT taper, denom; taper = d_tap[7] * r + d_tap[6]; taper = taper * r + d_tap[5]; taper = taper * r + d_tap[4]; taper = taper * r + d_tap[3]; taper = taper * r + d_tap[2]; taper = taper * r + d_tap[1]; taper = taper * r + d_tap[0]; denom = r * r * r + shld; denom = pow(denom,0.3333333333333); return taper * EV_TO_KCAL_PER_MOL / denom; } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION void FixQEqReaxKokkos::mat_vec_item(int ii) const { const int i = d_ilist[ii]; const int itype = type(i); if (mask[i] & groupbit) { d_Hdia_inv[i] = 1.0 / params(itype).eta; d_b_s[i] = -params(itype).chi; d_b_t[i] = -1.0; d_t[i] = d_t_hist(i,2) + 3*(d_t_hist(i,0) - d_t_hist(i,1)); d_s[i] = 4*(d_s_hist(i,0)+d_s_hist(i,2))-(6*d_s_hist(i,1)+d_s_hist(i,3)); } } /* ---------------------------------------------------------------------- */ template void FixQEqReaxKokkos::cg_solve1() // b = b_s, x = s; { const int inum = list->inum; const int ignum = inum + list->gnum; F_FLOAT tmp, sig_old, b_norm; const int teamsize = TEAMSIZE; // sparse_matvec( &H, x, q ); FixQEqReaxKokkosSparse12Functor sparse12_functor(this); Kokkos::parallel_for(inum,sparse12_functor); DeviceType::fence(); if (neighflag != FULL) { Kokkos::parallel_for(Kokkos::RangePolicy(nlocal,nlocal+atom->nghost),*this); DeviceType::fence(); if (neighflag == HALF) { FixQEqReaxKokkosSparse13Functor sparse13_functor(this); Kokkos::parallel_for(inum,sparse13_functor); } else { FixQEqReaxKokkosSparse13Functor sparse13_functor(this); Kokkos::parallel_for(inum,sparse13_functor); } } else { Kokkos::parallel_for(Kokkos::TeamPolicy (inum, teamsize), *this); } DeviceType::fence(); if (neighflag != FULL) { k_o.template modify(); k_o.template sync(); comm->reverse_comm_fix(this); //Coll_vector( q ); k_o.template modify(); k_o.template sync(); } // vector_sum( r , 1., b, -1., q, nn ); // preconditioning: d[j] = r[j] * Hdia_inv[j]; // b_norm = parallel_norm( b, nn ); F_FLOAT my_norm = 0.0; FixQEqReaxKokkosNorm1Functor norm1_functor(this); Kokkos::parallel_reduce(inum,norm1_functor,my_norm); DeviceType::fence(); F_FLOAT norm_sqr = 0.0; MPI_Allreduce( &my_norm, &norm_sqr, 1, MPI_DOUBLE, MPI_SUM, world ); b_norm = sqrt(norm_sqr); DeviceType::fence(); // sig_new = parallel_dot( r, d, nn); F_FLOAT my_dot = 0.0; FixQEqReaxKokkosDot1Functor dot1_functor(this); Kokkos::parallel_reduce(inum,dot1_functor,my_dot); DeviceType::fence(); F_FLOAT dot_sqr = 0.0; MPI_Allreduce( &my_dot, &dot_sqr, 1, MPI_DOUBLE, MPI_SUM, world ); F_FLOAT sig_new = dot_sqr; DeviceType::fence(); int loop; const int loopmax = 200; for (loop = 1; loop < loopmax & sqrt(sig_new)/b_norm > tolerance; loop++) { // comm->forward_comm_fix(this); //Dist_vector( d ); pack_flag = 1; k_d.template modify(); k_d.template sync(); comm->forward_comm_fix(this); k_d.template modify(); k_d.template sync(); // sparse_matvec( &H, d, q ); FixQEqReaxKokkosSparse22Functor sparse22_functor(this); Kokkos::parallel_for(inum,sparse22_functor); DeviceType::fence(); if (neighflag != FULL) { Kokkos::parallel_for(Kokkos::RangePolicy(nlocal,nlocal+atom->nghost),*this); DeviceType::fence(); if (neighflag == HALF) { FixQEqReaxKokkosSparse23Functor sparse23_functor(this); Kokkos::parallel_for(inum,sparse23_functor); } else { FixQEqReaxKokkosSparse23Functor sparse23_functor(this); Kokkos::parallel_for(inum,sparse23_functor); } } else { Kokkos::parallel_for(Kokkos::TeamPolicy (inum, teamsize), *this); } DeviceType::fence(); if (neighflag != FULL) { k_o.template modify(); k_o.template sync(); comm->reverse_comm_fix(this); //Coll_vector( q ); k_o.template modify(); k_o.template sync(); } // tmp = parallel_dot( d, q, nn); my_dot = dot_sqr = 0.0; FixQEqReaxKokkosDot2Functor dot2_functor(this); Kokkos::parallel_reduce(inum,dot2_functor,my_dot); DeviceType::fence(); MPI_Allreduce( &my_dot, &dot_sqr, 1, MPI_DOUBLE, MPI_SUM, world ); tmp = dot_sqr; alpha = sig_new / tmp; sig_old = sig_new; // vector_add( s, alpha, d, nn ); // vector_add( r, -alpha, q, nn ); my_dot = dot_sqr = 0.0; FixQEqReaxKokkosPrecon1Functor precon1_functor(this); Kokkos::parallel_for(inum,precon1_functor); DeviceType::fence(); // preconditioning: p[j] = r[j] * Hdia_inv[j]; // sig_new = parallel_dot( r, p, nn); FixQEqReaxKokkosPreconFunctor precon_functor(this); Kokkos::parallel_reduce(inum,precon_functor,my_dot); DeviceType::fence(); MPI_Allreduce( &my_dot, &dot_sqr, 1, MPI_DOUBLE, MPI_SUM, world ); sig_new = dot_sqr; beta = sig_new / sig_old; // vector_sum( d, 1., p, beta, d, nn ); FixQEqReaxKokkosVecSum2Functor vecsum2_functor(this); Kokkos::parallel_for(inum,vecsum2_functor); DeviceType::fence(); } if (loop >= loopmax && comm->me == 0) { char str[128]; sprintf(str,"Fix qeq/reax cg_solve1 convergence failed after %d iterations " "at " BIGINT_FORMAT " step: %f",loop,update->ntimestep,sqrt(sig_new)/b_norm); error->warning(FLERR,str); //error->all(FLERR,str); } } /* ---------------------------------------------------------------------- */ template void FixQEqReaxKokkos::cg_solve2() // b = b_t, x = t; { const int inum = list->inum; const int ignum = inum + list->gnum; F_FLOAT tmp, sig_old, b_norm; const int teamsize = TEAMSIZE; // sparse_matvec( &H, x, q ); FixQEqReaxKokkosSparse32Functor sparse32_functor(this); Kokkos::parallel_for(inum,sparse32_functor); DeviceType::fence(); if (neighflag != FULL) { Kokkos::parallel_for(Kokkos::RangePolicy(nlocal,nlocal+atom->nghost),*this); DeviceType::fence(); if (neighflag == HALF) { FixQEqReaxKokkosSparse33Functor sparse33_functor(this); Kokkos::parallel_for(inum,sparse33_functor); } else { FixQEqReaxKokkosSparse33Functor sparse33_functor(this); Kokkos::parallel_for(inum,sparse33_functor); } } else { Kokkos::parallel_for(Kokkos::TeamPolicy (inum, teamsize), *this); } DeviceType::fence(); if (neighflag != FULL) { k_o.template modify(); k_o.template sync(); comm->reverse_comm_fix(this); //Coll_vector( q ); k_o.template modify(); k_o.template sync(); } // vector_sum( r , 1., b, -1., q, nn ); // preconditioning: d[j] = r[j] * Hdia_inv[j]; // b_norm = parallel_norm( b, nn ); F_FLOAT my_norm = 0.0; FixQEqReaxKokkosNorm2Functor norm2_functor(this); Kokkos::parallel_reduce(inum,norm2_functor,my_norm); DeviceType::fence(); F_FLOAT norm_sqr = 0.0; MPI_Allreduce( &my_norm, &norm_sqr, 1, MPI_DOUBLE, MPI_SUM, world ); b_norm = sqrt(norm_sqr); DeviceType::fence(); // sig_new = parallel_dot( r, d, nn); F_FLOAT my_dot = 0.0; FixQEqReaxKokkosDot1Functor dot1_functor(this); Kokkos::parallel_reduce(inum,dot1_functor,my_dot); DeviceType::fence(); F_FLOAT dot_sqr = 0.0; MPI_Allreduce( &my_dot, &dot_sqr, 1, MPI_DOUBLE, MPI_SUM, world ); F_FLOAT sig_new = dot_sqr; DeviceType::fence(); int loop; const int loopmax = 200; for (loop = 1; loop < loopmax & sqrt(sig_new)/b_norm > tolerance; loop++) { // comm->forward_comm_fix(this); //Dist_vector( d ); pack_flag = 1; k_d.template modify(); k_d.template sync(); comm->forward_comm_fix(this); k_d.template modify(); k_d.template sync(); // sparse_matvec( &H, d, q ); FixQEqReaxKokkosSparse22Functor sparse22_functor(this); Kokkos::parallel_for(inum,sparse22_functor); DeviceType::fence(); if (neighflag != FULL) { Kokkos::parallel_for(Kokkos::RangePolicy(nlocal,nlocal+atom->nghost),*this); DeviceType::fence(); if (neighflag == HALF) { FixQEqReaxKokkosSparse23Functor sparse23_functor(this); Kokkos::parallel_for(inum,sparse23_functor); } else { FixQEqReaxKokkosSparse23Functor sparse23_functor(this); Kokkos::parallel_for(inum,sparse23_functor); } } else { Kokkos::parallel_for(Kokkos::TeamPolicy (inum, teamsize), *this); } DeviceType::fence(); if (neighflag != FULL) { k_o.template modify(); k_o.template sync(); comm->reverse_comm_fix(this); //Coll_vector( q ); k_o.template modify(); k_o.template sync(); } // tmp = parallel_dot( d, q, nn); my_dot = dot_sqr = 0.0; FixQEqReaxKokkosDot2Functor dot2_functor(this); Kokkos::parallel_reduce(inum,dot2_functor,my_dot); DeviceType::fence(); MPI_Allreduce( &my_dot, &dot_sqr, 1, MPI_DOUBLE, MPI_SUM, world ); tmp = dot_sqr; DeviceType::fence(); alpha = sig_new / tmp; sig_old = sig_new; // vector_add( t, alpha, d, nn ); // vector_add( r, -alpha, q, nn ); my_dot = dot_sqr = 0.0; FixQEqReaxKokkosPrecon2Functor precon2_functor(this); Kokkos::parallel_for(inum,precon2_functor); DeviceType::fence(); // preconditioning: p[j] = r[j] * Hdia_inv[j]; // sig_new = parallel_dot( r, p, nn); FixQEqReaxKokkosPreconFunctor precon_functor(this); Kokkos::parallel_reduce(inum,precon_functor,my_dot); DeviceType::fence(); MPI_Allreduce( &my_dot, &dot_sqr, 1, MPI_DOUBLE, MPI_SUM, world ); sig_new = dot_sqr; beta = sig_new / sig_old; // vector_sum( d, 1., p, beta, d, nn ); FixQEqReaxKokkosVecSum2Functor vecsum2_functor(this); Kokkos::parallel_for(inum,vecsum2_functor); DeviceType::fence(); } if (loop >= loopmax && comm->me == 0) { char str[128]; sprintf(str,"Fix qeq/reax cg_solve2 convergence failed after %d iterations " "at " BIGINT_FORMAT " step: %f",loop,update->ntimestep,sqrt(sig_new)/b_norm); error->warning(FLERR,str); //error->all(FLERR,str); } } /* ---------------------------------------------------------------------- */ template void FixQEqReaxKokkos::calculate_q() { F_FLOAT sum, sum_all; const int inum = list->inum; // s_sum = parallel_vector_acc( s, nn ); sum = sum_all = 0.0; FixQEqReaxKokkosVecAcc1Functor vecacc1_functor(this); Kokkos::parallel_reduce(inum,vecacc1_functor,sum); DeviceType::fence(); MPI_Allreduce(&sum, &sum_all, 1, MPI_DOUBLE, MPI_SUM, world ); const F_FLOAT s_sum = sum_all; // t_sum = parallel_vector_acc( t, nn); sum = sum_all = 0.0; FixQEqReaxKokkosVecAcc2Functor vecacc2_functor(this); Kokkos::parallel_reduce(inum,vecacc2_functor,sum); DeviceType::fence(); MPI_Allreduce(&sum, &sum_all, 1, MPI_DOUBLE, MPI_SUM, world ); const F_FLOAT t_sum = sum_all; // u = s_sum / t_sum; delta = s_sum/t_sum; // q[i] = s[i] - u * t[i]; FixQEqReaxKokkosCalculateQFunctor calculateQ_functor(this); Kokkos::parallel_for(inum,calculateQ_functor); DeviceType::fence(); pack_flag = 4; //comm->forward_comm_fix( this ); //Dist_vector( atom->q ); atomKK->k_q.modify(); atomKK->k_q.sync(); comm->forward_comm_fix(this); atomKK->k_q.modify(); atomKK->k_q.sync(); } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION void FixQEqReaxKokkos::sparse12_item(int ii) const { const int i = d_ilist[ii]; const int itype = type(i); if (mask[i] & groupbit) { d_o[i] = params(itype).eta * d_s[i]; } } /* ---------------------------------------------------------------------- */ template template KOKKOS_INLINE_FUNCTION void FixQEqReaxKokkos::sparse13_item(int ii) const { // The q array is atomic for Half/Thread neighbor style Kokkos::View::value> > a_o = d_o; const int i = d_ilist[ii]; if (mask[i] & groupbit) { F_FLOAT tmp = 0.0; for(int jj = d_firstnbr[i]; jj < d_firstnbr[i] + d_numnbrs[i]; jj++) { const int j = d_jlist(jj); tmp += d_val(jj) * d_s[j]; a_o[j] += d_val(jj) * d_s[i]; } a_o[i] += tmp; } } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION void FixQEqReaxKokkos::operator() (TagSparseMatvec1, const membertype1 &team) const { const int i = d_ilist[team.league_rank()]; if (mask[i] & groupbit) { F_FLOAT doitmp; Kokkos::parallel_reduce(Kokkos::TeamThreadRange(team, d_firstnbr[i], d_firstnbr[i] + d_numnbrs[i]), [&] (const int &jj, F_FLOAT &doi) { const int j = d_jlist(jj); doi += d_val(jj) * d_s[j]; }, doitmp); Kokkos::single(Kokkos::PerTeam(team), [&] () {d_o[i] += doitmp;}); } } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION void FixQEqReaxKokkos::sparse22_item(int ii) const { const int i = d_ilist[ii]; const int itype = type(i); if (mask[i] & groupbit) { d_o[i] = params(itype).eta * d_d[i]; } } /* ---------------------------------------------------------------------- */ template template KOKKOS_INLINE_FUNCTION void FixQEqReaxKokkos::sparse23_item(int ii) const { // The q array is atomic for Half/Thread neighbor style Kokkos::View::value> > a_o = d_o; const int i = d_ilist[ii]; if (mask[i] & groupbit) { F_FLOAT tmp = 0.0; for(int jj = d_firstnbr[i]; jj < d_firstnbr[i] + d_numnbrs[i]; jj++) { const int j = d_jlist(jj); tmp += d_val(jj) * d_d[j]; a_o[j] += d_val(jj) * d_d[i]; } a_o[i] += tmp; } } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION void FixQEqReaxKokkos::operator() (TagSparseMatvec2, const membertype2 &team) const { const int i = d_ilist[team.league_rank()]; if (mask[i] & groupbit) { F_FLOAT doitmp; Kokkos::parallel_reduce(Kokkos::TeamThreadRange(team, d_firstnbr[i], d_firstnbr[i] + d_numnbrs[i]), [&] (const int &jj, F_FLOAT &doi) { const int j = d_jlist(jj); doi += d_val(jj) * d_d[j]; }, doitmp); Kokkos::single(Kokkos::PerTeam(team), [&] () {d_o[i] += doitmp; }); } } template KOKKOS_INLINE_FUNCTION void FixQEqReaxKokkos::operator() (TagZeroQGhosts, const int &i) const { if (mask[i] & groupbit) d_o[i] = 0.0; } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION void FixQEqReaxKokkos::sparse32_item(int ii) const { const int i = d_ilist[ii]; const int itype = type(i); if (mask[i] & groupbit) d_o[i] = params(itype).eta * d_t[i]; } /* ---------------------------------------------------------------------- */ template template KOKKOS_INLINE_FUNCTION void FixQEqReaxKokkos::sparse33_item(int ii) const { // The q array is atomic for Half/Thread neighbor style Kokkos::View::value> > a_o = d_o; const int i = d_ilist[ii]; if (mask[i] & groupbit) { F_FLOAT tmp = 0.0; for(int jj = d_firstnbr[i]; jj < d_firstnbr[i] + d_numnbrs[i]; jj++) { const int j = d_jlist(jj); tmp += d_val(jj) * d_t[j]; a_o[j] += d_val(jj) * d_t[i]; } a_o[i] += tmp; } } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION void FixQEqReaxKokkos::operator() (TagSparseMatvec3, const membertype3 &team) const { const int i = d_ilist[team.league_rank()]; if (mask[i] & groupbit) { F_FLOAT doitmp; Kokkos::parallel_reduce(Kokkos::TeamThreadRange(team, d_firstnbr[i], d_firstnbr[i] + d_numnbrs[i]), [&] (const int &jj, F_FLOAT &doi) { const int j = d_jlist(jj); doi += d_val(jj) * d_t[j]; }, doitmp); Kokkos::single(Kokkos::PerTeam(team), [&] () {d_o[i] += doitmp;}); } } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION void FixQEqReaxKokkos::vecsum2_item(int ii) const { const int i = d_ilist[ii]; if (mask[i] & groupbit) d_d[i] = 1.0 * d_p[i] + beta * d_d[i]; } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION double FixQEqReaxKokkos::norm1_item(int ii) const { F_FLOAT tmp = 0; const int i = d_ilist[ii]; if (mask[i] & groupbit) { d_r[i] = 1.0*d_b_s[i] + -1.0*d_o[i]; d_d[i] = d_r[i] * d_Hdia_inv[i]; tmp = d_b_s[i] * d_b_s[i]; } return tmp; } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION double FixQEqReaxKokkos::norm2_item(int ii) const { F_FLOAT tmp = 0; const int i = d_ilist[ii]; if (mask[i] & groupbit) { d_r[i] = 1.0*d_b_t[i] + -1.0*d_o[i]; d_d[i] = d_r[i] * d_Hdia_inv[i]; tmp = d_b_t[i] * d_b_t[i]; } return tmp; } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION double FixQEqReaxKokkos::dot1_item(int ii) const { F_FLOAT tmp = 0.0; const int i = d_ilist[ii]; if (mask[i] & groupbit) tmp = d_r[i] * d_d[i]; return tmp; } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION double FixQEqReaxKokkos::dot2_item(int ii) const { double tmp = 0.0; const int i = d_ilist[ii]; if (mask[i] & groupbit) { tmp = d_d[i] * d_o[i]; } return tmp; } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION void FixQEqReaxKokkos::precon1_item(int ii) const { const int i = d_ilist[ii]; if (mask[i] & groupbit) { d_s[i] += alpha * d_d[i]; d_r[i] += -alpha * d_o[i]; } } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION void FixQEqReaxKokkos::precon2_item(int ii) const { const int i = d_ilist[ii]; if (mask[i] & groupbit) { d_t[i] += alpha * d_d[i]; d_r[i] += -alpha * d_o[i]; } } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION double FixQEqReaxKokkos::precon_item(int ii) const { F_FLOAT tmp = 0.0; const int i = d_ilist[ii]; if (mask[i] & groupbit) { d_p[i] = d_r[i] * d_Hdia_inv[i]; tmp = d_r[i] * d_p[i]; } return tmp; } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION double FixQEqReaxKokkos::vecacc1_item(int ii) const { F_FLOAT tmp = 0.0; const int i = d_ilist[ii]; if (mask[i] & groupbit) tmp = d_s[i]; return tmp; } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION double FixQEqReaxKokkos::vecacc2_item(int ii) const { F_FLOAT tmp = 0.0; const int i = d_ilist[ii]; if (mask[i] & groupbit) { tmp = d_t[i]; } return tmp; } /* ---------------------------------------------------------------------- */ template KOKKOS_INLINE_FUNCTION void FixQEqReaxKokkos::calculate_q_item(int ii) const { const int i = d_ilist[ii]; if (mask[i] & groupbit) { q(i) = d_s[i] - delta * d_t[i]; for (int k = 4; k > 0; --k) { d_s_hist(i,k) = d_s_hist(i,k-1); d_t_hist(i,k) = d_t_hist(i,k-1); } d_s_hist(i,0) = d_s[i]; d_t_hist(i,0) = d_t[i]; } } /* ---------------------------------------------------------------------- */ template int FixQEqReaxKokkos::pack_forward_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int m; if( pack_flag == 1) for(m = 0; m < n; m++) buf[m] = h_d[list[m]]; else if( pack_flag == 2 ) for(m = 0; m < n; m++) buf[m] = h_s[list[m]]; else if( pack_flag == 3 ) for(m = 0; m < n; m++) buf[m] = h_t[list[m]]; else if( pack_flag == 4 ) for(m = 0; m < n; m++) buf[m] = atom->q[list[m]]; return n; } /* ---------------------------------------------------------------------- */ template void FixQEqReaxKokkos::unpack_forward_comm(int n, int first, double *buf) { int i, m; if( pack_flag == 1) for(m = 0, i = first; m < n; m++, i++) h_d[i] = buf[m]; else if( pack_flag == 2) for(m = 0, i = first; m < n; m++, i++) h_s[i] = buf[m]; else if( pack_flag == 3) for(m = 0, i = first; m < n; m++, i++) h_t[i] = buf[m]; else if( pack_flag == 4) for(m = 0, i = first; m < n; m++, i++) atom->q[i] = buf[m]; } /* ---------------------------------------------------------------------- */ template int FixQEqReaxKokkos::pack_reverse_comm(int n, int first, double *buf) { int i, m; for(m = 0, i = first; m < n; m++, i++) { buf[m] = h_o[i]; } return n; } /* ---------------------------------------------------------------------- */ template void FixQEqReaxKokkos::unpack_reverse_comm(int n, int *list, double *buf) { for(int m = 0; m < n; m++) { h_o[list[m]] += buf[m]; } } /* ---------------------------------------------------------------------- */ template void FixQEqReaxKokkos::cleanup_copy() { id = style = NULL; } /* ---------------------------------------------------------------------- memory usage of local atom-based arrays ------------------------------------------------------------------------- */ template double FixQEqReaxKokkos::memory_usage() { double bytes; bytes = atom->nmax*5*2 * sizeof(F_FLOAT); // s_hist & t_hist bytes += atom->nmax*8 * sizeof(F_FLOAT); // storage bytes += n_cap*2 * sizeof(int); // matrix... bytes += m_cap * sizeof(int); bytes += m_cap * sizeof(F_FLOAT); return bytes; } /* ---------------------------------------------------------------------- */\ namespace LAMMPS_NS { template class FixQEqReaxKokkos; #ifdef KOKKOS_HAVE_CUDA template class FixQEqReaxKokkos; #endif } \ No newline at end of file diff --git a/src/KOKKOS/fix_setforce_kokkos.cpp b/src/KOKKOS/fix_setforce_kokkos.cpp index 93e5e1937..27f7d100f 100644 --- a/src/KOKKOS/fix_setforce_kokkos.cpp +++ b/src/KOKKOS/fix_setforce_kokkos.cpp @@ -1,188 +1,189 @@ /* ---------------------------------------------------------------------- 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 #include #include "fix_setforce_kokkos.h" #include "atom_kokkos.h" #include "update.h" #include "modify.h" #include "domain.h" #include "region.h" #include "respa.h" #include "input.h" #include "variable.h" #include "memory.h" #include "error.h" #include "force.h" #include "atom_masks.h" using namespace LAMMPS_NS; using namespace FixConst; enum{NONE,CONSTANT,EQUAL,ATOM}; /* ---------------------------------------------------------------------- */ template FixSetForceKokkos::FixSetForceKokkos(LAMMPS *lmp, int narg, char **arg) : FixSetForce(lmp, narg, arg) { + kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; datamask_read = EMPTY_MASK; datamask_modify = EMPTY_MASK; memory->destroy(sforce); memory->create_kokkos(k_sforce,sforce,maxatom,3,"setforce:sforce"); } /* ---------------------------------------------------------------------- */ template FixSetForceKokkos::~FixSetForceKokkos() { if (copymode) return; memory->destroy_kokkos(k_sforce,sforce); sforce = NULL; } /* ---------------------------------------------------------------------- */ template void FixSetForceKokkos::init() { FixSetForce::init(); if (strstr(update->integrate_style,"respa")) error->all(FLERR,"Cannot (yet) use respa with Kokkos"); } /* ---------------------------------------------------------------------- */ template void FixSetForceKokkos::post_force(int vflag) { atomKK->sync(execution_space, X_MASK | F_MASK | MASK_MASK); x = atomKK->k_x.view(); f = atomKK->k_f.view(); mask = atomKK->k_mask.view(); int nlocal = atom->nlocal; // update region if necessary region = NULL; if (iregion >= 0) { region = domain->regions[iregion]; region->prematch(); d_match = DAT::t_int_1d("setforce:d_match",nlocal); region->match_all_kokkos(groupbit,d_match); } // reallocate sforce array if necessary if (varflag == ATOM && atom->nmax > maxatom) { maxatom = atom->nmax; memory->destroy_kokkos(k_sforce,sforce); memory->create_kokkos(k_sforce,sforce,maxatom,3,"setforce:sforce"); } foriginal[0] = foriginal[1] = foriginal[2] = 0.0; double_3 foriginal_kk; force_flag = 0; if (varflag == CONSTANT) { copymode = 1; Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlocal),*this,foriginal_kk); DeviceType::fence(); copymode = 0; // variable force, wrap with clear/add } else { atomKK->sync(Host,ALL_MASK); // this can be removed when variable class is ported to Kokkos modify->clearstep_compute(); if (xstyle == EQUAL) xvalue = input->variable->compute_equal(xvar); else if (xstyle == ATOM) input->variable->compute_atom(xvar,igroup,&sforce[0][0],3,0); if (ystyle == EQUAL) yvalue = input->variable->compute_equal(yvar); else if (ystyle == ATOM) input->variable->compute_atom(yvar,igroup,&sforce[0][1],3,0); if (zstyle == EQUAL) zvalue = input->variable->compute_equal(zvar); else if (zstyle == ATOM) input->variable->compute_atom(zvar,igroup,&sforce[0][2],3,0); modify->addstep_compute(update->ntimestep + 1); if (varflag == ATOM) { // this can be removed when variable class is ported to Kokkos k_sforce.modify(); k_sforce.sync(); } copymode = 1; Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlocal),*this,foriginal_kk); DeviceType::fence(); copymode = 0; } atomKK->modified(execution_space, F_MASK); foriginal[0] = foriginal_kk.d0; foriginal[1] = foriginal_kk.d1; foriginal[2] = foriginal_kk.d2; } template KOKKOS_INLINE_FUNCTION void FixSetForceKokkos::operator()(TagFixSetForceConstant, const int &i, double_3& foriginal_kk) const { if (mask[i] & groupbit) { if (region && !d_match[i]) return; foriginal_kk.d0 += f(i,0); foriginal_kk.d1 += f(i,1); foriginal_kk.d2 += f(i,2); if (xstyle) f(i,0) = xvalue; if (ystyle) f(i,1) = yvalue; if (zstyle) f(i,2) = zvalue; } } template KOKKOS_INLINE_FUNCTION void FixSetForceKokkos::operator()(TagFixSetForceNonConstant, const int &i, double_3& foriginal_kk) const { if (mask[i] & groupbit) { if (region && !d_match[i]) return; foriginal_kk.d0 += f(i,0); foriginal_kk.d1 += f(i,1); foriginal_kk.d2 += f(i,2); if (xstyle == ATOM) f(i,0) = d_sforce(i,0); else if (xstyle) f(i,0) = xvalue; if (ystyle == ATOM) f(i,1) = d_sforce(i,1); else if (ystyle) f(i,1) = yvalue; if (zstyle == ATOM) f(i,2) = d_sforce(i,2); else if (zstyle) f(i,2) = zvalue; } } namespace LAMMPS_NS { template class FixSetForceKokkos; #ifdef KOKKOS_HAVE_CUDA template class FixSetForceKokkos; #endif } diff --git a/src/KOKKOS/fix_wall_reflect_kokkos.cpp b/src/KOKKOS/fix_wall_reflect_kokkos.cpp index 27c008023..55be7e5cd 100644 --- a/src/KOKKOS/fix_wall_reflect_kokkos.cpp +++ b/src/KOKKOS/fix_wall_reflect_kokkos.cpp @@ -1,114 +1,115 @@ /* ---------------------------------------------------------------------- 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 #include #include "fix_wall_reflect_kokkos.h" #include "atom_kokkos.h" #include "comm.h" #include "update.h" #include "modify.h" #include "domain.h" #include "lattice.h" #include "input.h" #include "variable.h" #include "error.h" #include "force.h" #include "atom_masks.h" using namespace LAMMPS_NS; using namespace FixConst; enum{XLO=0,XHI=1,YLO=2,YHI=3,ZLO=4,ZHI=5}; enum{NONE=0,EDGE,CONSTANT,VARIABLE}; /* ---------------------------------------------------------------------- */ template FixWallReflectKokkos::FixWallReflectKokkos(LAMMPS *lmp, int narg, char **arg) : FixWallReflect(lmp, narg, arg) { + kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; datamask_read = X_MASK | V_MASK | MASK_MASK; datamask_modify = X_MASK | V_MASK; } /* ---------------------------------------------------------------------- */ template void FixWallReflectKokkos::post_integrate() { // coord = current position of wall // evaluate variable if necessary, wrap with clear/add atomKK->sync(execution_space,datamask_read); atomKK->modified(execution_space,datamask_modify); x = atomKK->k_x.view(); v = atomKK->k_v.view(); mask = atomKK->k_mask.view(); int nlocal = atom->nlocal; if (varflag) modify->clearstep_compute(); for (int m = 0; m < nwall; m++) { if (wallstyle[m] == VARIABLE) { coord = input->variable->compute_equal(varindex[m]); if (wallwhich[m] < YLO) coord *= xscale; else if (wallwhich[m] < ZLO) coord *= yscale; else coord *= zscale; } else coord = coord0[m]; dim = wallwhich[m] / 2; side = wallwhich[m] % 2; copymode = 1; Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); DeviceType::fence(); copymode = 0; } if (varflag) modify->addstep_compute(update->ntimestep + 1); } template KOKKOS_INLINE_FUNCTION void FixWallReflectKokkos::operator()(TagFixWallReflectPostIntegrate, const int &i) const { if (mask[i] & groupbit) { if (side == 0) { if (x(i,dim) < coord) { x(i,dim) = coord + (coord - x(i,dim)); v(i,dim) = -v(i,dim); } } else { if (x(i,dim) > coord) { x(i,dim) = coord - (x(i,dim) - coord); v(i,dim) = -v(i,dim); } } } } /* ---------------------------------------------------------------------- */ namespace LAMMPS_NS { template class FixWallReflectKokkos; #ifdef KOKKOS_HAVE_CUDA template class FixWallReflectKokkos; #endif } diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index 180e3d849..72bf094e4 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -1,290 +1,292 @@ /* ---------------------------------------------------------------------- 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 #include #include #include #include #include #include "kokkos.h" #include "lammps.h" #include "force.h" #include "neighbor_kokkos.h" #include "neigh_list_kokkos.h" #include "error.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) { kokkos_exists = 1; lmp->kokkos = this; + auto_sync = 1; + int me = 0; MPI_Comm_rank(world,&me); if (me == 0) error->message(FLERR,"KOKKOS mode is enabled"); // process any command-line args that invoke Kokkos settings ngpu = 0; int device = 0; num_threads = 1; numa = 1; int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"d") == 0 || strcmp(arg[iarg],"device") == 0) { if (iarg+2 > narg) error->all(FLERR,"Invalid Kokkos command-line args"); device = atoi(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"g") == 0 || strcmp(arg[iarg],"gpus") == 0) { #ifndef KOKKOS_HAVE_CUDA error->all(FLERR,"GPUs are requested but Kokkos has not been compiled for CUDA"); #endif if (iarg+2 > narg) error->all(FLERR,"Invalid Kokkos command-line args"); ngpu = atoi(arg[iarg+1]); int skip_gpu = 9999; if (iarg+2 < narg && isdigit(arg[iarg+2][0])) { skip_gpu = atoi(arg[iarg+2]); iarg++; } iarg += 2; char *str; if ((str = getenv("SLURM_LOCALID"))) { int local_rank = atoi(str); device = local_rank % ngpu; if (device >= skip_gpu) device++; } if ((str = getenv("MV2_COMM_WORLD_LOCAL_RANK"))) { int local_rank = atoi(str); device = local_rank % ngpu; if (device >= skip_gpu) device++; } if ((str = getenv("OMPI_COMM_WORLD_LOCAL_RANK"))) { int local_rank = atoi(str); device = local_rank % ngpu; if (device >= skip_gpu) device++; } } else if (strcmp(arg[iarg],"t") == 0 || strcmp(arg[iarg],"threads") == 0) { num_threads = atoi(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"n") == 0 || strcmp(arg[iarg],"numa") == 0) { numa = atoi(arg[iarg+1]); iarg += 2; } else error->all(FLERR,"Invalid Kokkos command-line args"); } // initialize Kokkos if (me == 0) { if (screen) fprintf(screen," using %d GPU(s)\n",ngpu); if (logfile) fprintf(logfile," using %d GPU(s)\n",ngpu); } #ifdef KOKKOS_HAVE_CUDA if (ngpu <= 0) error->all(FLERR,"Kokkos has been compiled for CUDA but no GPUs are requested"); Kokkos::HostSpace::execution_space::initialize(num_threads,numa); Kokkos::Cuda::SelectDevice select_device(device); Kokkos::Cuda::initialize(select_device); #else LMPHostType::initialize(num_threads,numa); #endif // default settings for package kokkos command neighflag = FULL; exchange_comm_classic = 0; forward_comm_classic = 0; exchange_comm_on_host = 0; forward_comm_on_host = 0; #ifdef KILL_KOKKOS_ON_SIGSEGV signal(SIGSEGV, my_signal_handler); #endif } /* ---------------------------------------------------------------------- */ KokkosLMP::~KokkosLMP() { // finalize Kokkos #ifdef KOKKOS_HAVE_CUDA Kokkos::Cuda::finalize(); Kokkos::HostSpace::execution_space::finalize(); #else LMPHostType::finalize(); #endif } /* ---------------------------------------------------------------------- invoked by package kokkos command ------------------------------------------------------------------------- */ void KokkosLMP::accelerator(int narg, char **arg) { // defaults neighflag = FULL; int newtonflag = 0; double binsize = 0.0; exchange_comm_classic = forward_comm_classic = 0; exchange_comm_on_host = forward_comm_on_host = 0; int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"neigh") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal package kokkos command"); if (strcmp(arg[iarg+1],"full") == 0) neighflag = FULL; else if (strcmp(arg[iarg+1],"half") == 0) { if (num_threads > 1 || ngpu > 0) neighflag = HALFTHREAD; else neighflag = HALF; } else if (strcmp(arg[iarg+1],"n2") == 0) neighflag = N2; else if (strcmp(arg[iarg+1],"full/cluster") == 0) neighflag = FULLCLUSTER; else error->all(FLERR,"Illegal package kokkos command"); iarg += 2; } else if (strcmp(arg[iarg],"binsize") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal package kokkos command"); binsize = force->numeric(FLERR,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"newton") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal package kokkos command"); if (strcmp(arg[iarg+1],"off") == 0) newtonflag = 0; else if (strcmp(arg[iarg+1],"on") == 0) newtonflag = 1; else error->all(FLERR,"Illegal package kokkos command"); iarg += 2; } else if (strcmp(arg[iarg],"comm") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal package kokkos command"); if (strcmp(arg[iarg+1],"no") == 0) { exchange_comm_classic = forward_comm_classic = 1; } else if (strcmp(arg[iarg+1],"host") == 0) { exchange_comm_classic = forward_comm_classic = 0; exchange_comm_on_host = forward_comm_on_host = 1; } else if (strcmp(arg[iarg+1],"device") == 0) { exchange_comm_classic = forward_comm_classic = 0; exchange_comm_on_host = forward_comm_on_host = 0; } else error->all(FLERR,"Illegal package kokkos command"); iarg += 2; } else if (strcmp(arg[iarg],"comm/exchange") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal package kokkos command"); if (strcmp(arg[iarg+1],"no") == 0) exchange_comm_classic = 1; else if (strcmp(arg[iarg+1],"host") == 0) { exchange_comm_classic = 0; exchange_comm_on_host = 1; } else if (strcmp(arg[iarg+1],"device") == 0) { exchange_comm_classic = 0; exchange_comm_on_host = 0; } else error->all(FLERR,"Illegal package kokkos command"); iarg += 2; } else if (strcmp(arg[iarg],"comm/forward") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal package kokkos command"); if (strcmp(arg[iarg+1],"no") == 0) forward_comm_classic = 1; else if (strcmp(arg[iarg+1],"host") == 0) { forward_comm_classic = 0; forward_comm_on_host = 1; } else if (strcmp(arg[iarg+1],"device") == 0) { forward_comm_classic = 0; forward_comm_on_host = 0; } else error->all(FLERR,"Illegal package kokkos command"); iarg += 2; } else error->all(FLERR,"Illegal package kokkos command"); } // set newton flags // set neighbor binsize, same as neigh_modify command force->newton = force->newton_pair = force->newton_bond = newtonflag; neighbor->binsize_user = binsize; if (binsize <= 0.0) neighbor->binsizeflag = 0; else neighbor->binsizeflag = 1; } /* ---------------------------------------------------------------------- called by Finish ------------------------------------------------------------------------- */ int KokkosLMP::neigh_list_kokkos(int m) { NeighborKokkos *nk = (NeighborKokkos *) neighbor; if (nk->lists_host[m] && nk->lists_host[m]->d_numneigh.dimension_0()) return 1; if (nk->lists_device[m] && nk->lists_device[m]->d_numneigh.dimension_0()) return 1; return 0; } /* ---------------------------------------------------------------------- called by Finish ------------------------------------------------------------------------- */ int KokkosLMP::neigh_count(int m) { int inum; int nneigh = 0; ArrayTypes::t_int_1d h_ilist; ArrayTypes::t_int_1d h_numneigh; NeighborKokkos *nk = (NeighborKokkos *) neighbor; if (nk->lists_host[m]) { inum = nk->lists_host[m]->inum; #ifndef KOKKOS_USE_CUDA_UVM h_ilist = Kokkos::create_mirror_view(nk->lists_host[m]->d_ilist); h_numneigh = Kokkos::create_mirror_view(nk->lists_host[m]->d_numneigh); #else h_ilist = nk->lists_host[m]->d_ilist; h_numneigh = nk->lists_host[m]->d_numneigh; #endif Kokkos::deep_copy(h_ilist,nk->lists_host[m]->d_ilist); Kokkos::deep_copy(h_numneigh,nk->lists_host[m]->d_numneigh); } else if (nk->lists_device[m]) { inum = nk->lists_device[m]->inum; #ifndef KOKKOS_USE_CUDA_UVM h_ilist = Kokkos::create_mirror_view(nk->lists_device[m]->d_ilist); h_numneigh = Kokkos::create_mirror_view(nk->lists_device[m]->d_numneigh); #else h_ilist = nk->lists_device[m]->d_ilist; h_numneigh = nk->lists_device[m]->d_numneigh; #endif Kokkos::deep_copy(h_ilist,nk->lists_device[m]->d_ilist); Kokkos::deep_copy(h_numneigh,nk->lists_device[m]->d_numneigh); } for (int i = 0; i < inum; i++) nneigh += h_numneigh[h_ilist[i]]; return nneigh; } void KokkosLMP::my_signal_handler(int sig) { if (sig == SIGSEGV) { kill(getpid(),SIGABRT); } } \ No newline at end of file diff --git a/src/KOKKOS/kokkos.h b/src/KOKKOS/kokkos.h index f6d340428..1058affcf 100644 --- a/src/KOKKOS/kokkos.h +++ b/src/KOKKOS/kokkos.h @@ -1,70 +1,71 @@ /* -*- 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 KOKKOS_LMP_H #define KOKKOS_LMP_H #include "pointers.h" #include "kokkos_type.h" namespace LAMMPS_NS { class KokkosLMP : protected Pointers { public: int kokkos_exists; int neighflag; int exchange_comm_classic; int forward_comm_classic; int exchange_comm_on_host; int forward_comm_on_host; int num_threads,ngpu; int numa; + int auto_sync; KokkosLMP(class LAMMPS *, int, char **); ~KokkosLMP(); void accelerator(int, char **); int neigh_list_kokkos(int); int neigh_count(int); private: static void my_signal_handler(int); }; } #endif /* ERROR/WARNING messages: E: Invalid Kokkos command-line args Self-explanatory. See Section 2.7 of the manual for details. E: GPUs are requested but Kokkos has not been compiled for CUDA Recompile Kokkos with CUDA support to use GPUs. E: Kokkos has been compiled for CUDA but no GPUs are requested One or more GPUs must be used when Kokkos is compiled for CUDA. E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. E: Must use Kokkos half/thread or full neighbor list with threads or GPUs Using Kokkos half-neighbor lists with threading is not allowed. */ diff --git a/src/KOKKOS/modify_kokkos.cpp b/src/KOKKOS/modify_kokkos.cpp index b1b98144a..9a035ac20 100644 --- a/src/KOKKOS/modify_kokkos.cpp +++ b/src/KOKKOS/modify_kokkos.cpp @@ -1,586 +1,661 @@ /* ---------------------------------------------------------------------- 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 "modify_kokkos.h" #include "atom_kokkos.h" #include "update.h" #include "fix.h" #include "compute.h" +#include "kokkos.h" using namespace LAMMPS_NS; #define BIG 1.0e20 /* ---------------------------------------------------------------------- */ ModifyKokkos::ModifyKokkos(LAMMPS *lmp) : Modify(lmp) { atomKK = (AtomKokkos *) atom; } /* ---------------------------------------------------------------------- setup for run, calls setup() of all fixes and computes called from Verlet, RESPA, Min ------------------------------------------------------------------------- */ void ModifyKokkos::setup(int vflag) { // compute setup needs to come before fix setup // b/c NH fixes need use DOF of temperature computes for (int i = 0; i < ncompute; i++) compute[i]->setup(); if (update->whichflag == 1) for (int i = 0; i < nfix; i++) { atomKK->sync(fix[i]->execution_space,fix[i]->datamask_read); + if (!fix[i]->kokkosable) lmp->kokkos->auto_sync = 1; fix[i]->setup(vflag); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[i]->execution_space,fix[i]->datamask_modify); } else if (update->whichflag == 2) for (int i = 0; i < nfix; i++) { atomKK->sync(fix[i]->execution_space,fix[i]->datamask_read); + if (!fix[i]->kokkosable) lmp->kokkos->auto_sync = 1; fix[i]->min_setup(vflag); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[i]->execution_space,fix[i]->datamask_modify); } } /* ---------------------------------------------------------------------- setup pre_exchange call, only for fixes that define pre_exchange called from Verlet, RESPA, Min, and WriteRestart with whichflag = 0 ------------------------------------------------------------------------- */ void ModifyKokkos::setup_pre_exchange() { if (update->whichflag <= 1) for (int i = 0; i < n_pre_exchange; i++) { atomKK->sync(fix[list_pre_exchange[i]]->execution_space, fix[list_pre_exchange[i]]->datamask_read); + if (!fix[list_pre_exchange[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_pre_exchange[i]]->setup_pre_exchange(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_pre_exchange[i]]->execution_space, fix[list_pre_exchange[i]]->datamask_modify); } else if (update->whichflag == 2) for (int i = 0; i < n_min_pre_exchange; i++) { atomKK->sync(fix[list_min_pre_exchange[i]]->execution_space, fix[list_min_pre_exchange[i]]->datamask_read); + if (!fix[list_min_pre_exchange[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_min_pre_exchange[i]]->min_setup_pre_exchange(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_min_pre_exchange[i]]->execution_space, fix[list_min_pre_exchange[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- setup pre_neighbor call, only for fixes that define pre_neighbor called from Verlet, RESPA ------------------------------------------------------------------------- */ void ModifyKokkos::setup_pre_neighbor() { if (update->whichflag == 1) for (int i = 0; i < n_pre_neighbor; i++) { atomKK->sync(fix[list_pre_neighbor[i]]->execution_space, fix[list_pre_neighbor[i]]->datamask_read); + if (!fix[list_pre_neighbor[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_pre_neighbor[i]]->setup_pre_neighbor(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_pre_neighbor[i]]->execution_space, fix[list_pre_neighbor[i]]->datamask_modify); } else if (update->whichflag == 2) for (int i = 0; i < n_min_pre_neighbor; i++) { atomKK->sync(fix[list_min_pre_neighbor[i]]->execution_space, fix[list_min_pre_neighbor[i]]->datamask_read); + if (!fix[list_min_pre_neighbor[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_min_pre_neighbor[i]]->min_setup_pre_neighbor(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_min_pre_neighbor[i]]->execution_space, fix[list_min_pre_neighbor[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- setup pre_force call, only for fixes that define pre_force called from Verlet, RESPA, Min ------------------------------------------------------------------------- */ void ModifyKokkos::setup_pre_force(int vflag) { if (update->whichflag == 1) for (int i = 0; i < n_pre_force; i++) { atomKK->sync(fix[list_pre_force[i]]->execution_space, fix[list_pre_force[i]]->datamask_read); + if (!fix[list_pre_force[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_pre_force[i]]->setup_pre_force(vflag); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_pre_force[i]]->execution_space, fix[list_pre_force[i]]->datamask_modify); } else if (update->whichflag == 2) for (int i = 0; i < n_min_pre_force; i++) { atomKK->sync(fix[list_min_pre_force[i]]->execution_space, fix[list_min_pre_force[i]]->datamask_read); + if (!fix[list_min_pre_force[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_min_pre_force[i]]->min_setup_pre_force(vflag); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_min_pre_force[i]]->execution_space, fix[list_min_pre_force[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- 1st half of integrate call, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::initial_integrate(int vflag) { for (int i = 0; i < n_initial_integrate; i++) { atomKK->sync(fix[list_initial_integrate[i]]->execution_space, fix[list_initial_integrate[i]]->datamask_read); + if (!fix[list_initial_integrate[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_initial_integrate[i]]->initial_integrate(vflag); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_initial_integrate[i]]->execution_space, fix[list_initial_integrate[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- post_integrate call, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::post_integrate() { for (int i = 0; i < n_post_integrate; i++) { atomKK->sync(fix[list_post_integrate[i]]->execution_space, fix[list_post_integrate[i]]->datamask_read); + if (!fix[list_post_integrate[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_post_integrate[i]]->post_integrate(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_post_integrate[i]]->execution_space, fix[list_post_integrate[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- pre_exchange call, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::pre_exchange() { for (int i = 0; i < n_pre_exchange; i++) { atomKK->sync(fix[list_pre_exchange[i]]->execution_space, fix[list_pre_exchange[i]]->datamask_read); + if (!fix[list_pre_exchange[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_pre_exchange[i]]->pre_exchange(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_pre_exchange[i]]->execution_space, fix[list_pre_exchange[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- pre_neighbor call, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::pre_neighbor() { for (int i = 0; i < n_pre_neighbor; i++) { atomKK->sync(fix[list_pre_neighbor[i]]->execution_space, fix[list_pre_neighbor[i]]->datamask_read); + if (!fix[list_pre_neighbor[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_pre_neighbor[i]]->pre_neighbor(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_pre_neighbor[i]]->execution_space, fix[list_pre_neighbor[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- pre_force call, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::pre_force(int vflag) { for (int i = 0; i < n_pre_force; i++) { atomKK->sync(fix[list_pre_force[i]]->execution_space, fix[list_pre_force[i]]->datamask_read); + if (!fix[list_pre_force[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_pre_force[i]]->pre_force(vflag); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_pre_force[i]]->execution_space, fix[list_pre_force[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- post_force call, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::post_force(int vflag) { for (int i = 0; i < n_post_force; i++) { atomKK->sync(fix[list_post_force[i]]->execution_space, fix[list_post_force[i]]->datamask_read); + if (!fix[list_post_force[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_post_force[i]]->post_force(vflag); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_post_force[i]]->execution_space, fix[list_post_force[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- 2nd half of integrate call, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::final_integrate() { for (int i = 0; i < n_final_integrate; i++) { atomKK->sync(fix[list_final_integrate[i]]->execution_space, fix[list_final_integrate[i]]->datamask_read); + if (!fix[list_final_integrate[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_final_integrate[i]]->final_integrate(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_final_integrate[i]]->execution_space, fix[list_final_integrate[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- end-of-timestep call, only for relevant fixes only call fix->end_of_step() on timesteps that are multiples of nevery ------------------------------------------------------------------------- */ void ModifyKokkos::end_of_step() { for (int i = 0; i < n_end_of_step; i++) if (update->ntimestep % end_of_step_every[i] == 0) { atomKK->sync(fix[list_end_of_step[i]]->execution_space, fix[list_end_of_step[i]]->datamask_read); + if (!fix[list_end_of_step[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_end_of_step[i]]->end_of_step(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_end_of_step[i]]->execution_space, fix[list_end_of_step[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- thermo energy call, only for relevant fixes called by Thermo class compute_scalar() is fix call to return energy ------------------------------------------------------------------------- */ double ModifyKokkos::thermo_energy() { double energy = 0.0; for (int i = 0; i < n_thermo_energy; i++) { atomKK->sync(fix[list_thermo_energy[i]]->execution_space, fix[list_thermo_energy[i]]->datamask_read); + if (!fix[list_thermo_energy[i]]->kokkosable) lmp->kokkos->auto_sync = 1; energy += fix[list_thermo_energy[i]]->compute_scalar(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_thermo_energy[i]]->execution_space, fix[list_thermo_energy[i]]->datamask_modify); } return energy; } /* ---------------------------------------------------------------------- post_run call ------------------------------------------------------------------------- */ void ModifyKokkos::post_run() { for (int i = 0; i < nfix; i++) { atomKK->sync(fix[i]->execution_space, fix[i]->datamask_read); + if (!fix[i]->kokkosable) lmp->kokkos->auto_sync = 1; fix[i]->post_run(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[i]->execution_space, fix[i]->datamask_modify); } } /* ---------------------------------------------------------------------- setup rRESPA pre_force call, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::setup_pre_force_respa(int vflag, int ilevel) { for (int i = 0; i < n_pre_force; i++) { atomKK->sync(fix[list_pre_force[i]]->execution_space, fix[list_pre_force[i]]->datamask_read); + if (!fix[list_pre_force[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_pre_force[i]]->setup_pre_force_respa(vflag,ilevel); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_pre_force[i]]->execution_space, fix[list_pre_force[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- 1st half of rRESPA integrate call, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::initial_integrate_respa(int vflag, int ilevel, int iloop) { for (int i = 0; i < n_initial_integrate_respa; i++) { atomKK->sync(fix[list_initial_integrate_respa[i]]->execution_space, fix[list_initial_integrate_respa[i]]->datamask_read); + if (!fix[list_initial_integrate_respa[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_initial_integrate_respa[i]]-> initial_integrate_respa(vflag,ilevel,iloop); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_initial_integrate_respa[i]]->execution_space, fix[list_initial_integrate_respa[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- rRESPA post_integrate call, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::post_integrate_respa(int ilevel, int iloop) { for (int i = 0; i < n_post_integrate_respa; i++) { atomKK->sync(fix[list_post_integrate_respa[i]]->execution_space, fix[list_post_integrate_respa[i]]->datamask_read); + if (!fix[list_post_integrate_respa[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_post_integrate_respa[i]]->post_integrate_respa(ilevel,iloop); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_post_integrate_respa[i]]->execution_space, fix[list_post_integrate_respa[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- rRESPA pre_force call, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::pre_force_respa(int vflag, int ilevel, int iloop) { for (int i = 0; i < n_pre_force_respa; i++) { atomKK->sync(fix[list_pre_force_respa[i]]->execution_space, fix[list_pre_force_respa[i]]->datamask_read); + if (!fix[list_pre_force_respa[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_pre_force_respa[i]]->pre_force_respa(vflag,ilevel,iloop); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_pre_force_respa[i]]->execution_space, fix[list_pre_force_respa[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- rRESPA post_force call, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::post_force_respa(int vflag, int ilevel, int iloop) { for (int i = 0; i < n_post_force_respa; i++) { atomKK->sync(fix[list_post_force_respa[i]]->execution_space, fix[list_post_force_respa[i]]->datamask_read); + if (!fix[list_post_force_respa[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_post_force_respa[i]]->post_force_respa(vflag,ilevel,iloop); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_post_force_respa[i]]->execution_space, fix[list_post_force_respa[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- 2nd half of rRESPA integrate call, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::final_integrate_respa(int ilevel, int iloop) { for (int i = 0; i < n_final_integrate_respa; i++) { atomKK->sync(fix[list_final_integrate_respa[i]]->execution_space, fix[list_final_integrate_respa[i]]->datamask_read); + if (!fix[list_final_integrate_respa[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_final_integrate_respa[i]]->final_integrate_respa(ilevel,iloop); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_final_integrate_respa[i]]->execution_space, fix[list_final_integrate_respa[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- minimizer pre-exchange call, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::min_pre_exchange() { for (int i = 0; i < n_min_pre_exchange; i++) { atomKK->sync(fix[list_min_pre_exchange[i]]->execution_space, fix[list_min_pre_exchange[i]]->datamask_read); + if (!fix[list_min_pre_exchange[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_min_pre_exchange[i]]->min_pre_exchange(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_min_pre_exchange[i]]->execution_space, fix[list_min_pre_exchange[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- minimizer pre-neighbor call, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::min_pre_neighbor() { for (int i = 0; i < n_min_pre_neighbor; i++) { atomKK->sync(fix[list_min_pre_neighbor[i]]->execution_space, fix[list_min_pre_neighbor[i]]->datamask_read); + if (!fix[list_min_pre_neighbor[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_min_pre_neighbor[i]]->min_pre_neighbor(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_min_pre_neighbor[i]]->execution_space, fix[list_min_pre_neighbor[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- minimizer pre-force call, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::min_pre_force(int vflag) { for (int i = 0; i < n_min_pre_force; i++) { atomKK->sync(fix[list_min_pre_force[i]]->execution_space, fix[list_min_pre_force[i]]->datamask_read); + if (!fix[list_min_pre_force[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_min_pre_force[i]]->min_pre_force(vflag); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_min_pre_force[i]]->execution_space, fix[list_min_pre_force[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- minimizer force adjustment call, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::min_post_force(int vflag) { for (int i = 0; i < n_min_post_force; i++) { atomKK->sync(fix[list_min_post_force[i]]->execution_space, fix[list_min_post_force[i]]->datamask_read); + if (!fix[list_min_post_force[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_min_post_force[i]]->min_post_force(vflag); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_min_post_force[i]]->execution_space, fix[list_min_post_force[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- minimizer energy/force evaluation, only for relevant fixes return energy and forces on extra degrees of freedom ------------------------------------------------------------------------- */ double ModifyKokkos::min_energy(double *fextra) { int ifix,index; index = 0; double eng = 0.0; for (int i = 0; i < n_min_energy; i++) { ifix = list_min_energy[i]; atomKK->sync(fix[ifix]->execution_space,fix[ifix]->datamask_read); + if (!fix[ifix]->kokkosable) lmp->kokkos->auto_sync = 1; eng += fix[ifix]->min_energy(&fextra[index]); index += fix[ifix]->min_dof(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[ifix]->execution_space,fix[ifix]->datamask_modify); } return eng; } /* ---------------------------------------------------------------------- store current state of extra dof, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::min_store() { for (int i = 0; i < n_min_energy; i++) { atomKK->sync(fix[list_min_energy[i]]->execution_space, fix[list_min_energy[i]]->datamask_read); + if (!fix[list_min_energy[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_min_energy[i]]->min_store(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_min_energy[i]]->execution_space, fix[list_min_energy[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- mange state of extra dof on a stack, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::min_clearstore() { for (int i = 0; i < n_min_energy; i++) { atomKK->sync(fix[list_min_energy[i]]->execution_space, fix[list_min_energy[i]]->datamask_read); + if (!fix[list_min_energy[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_min_energy[i]]->min_clearstore(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_min_energy[i]]->execution_space, fix[list_min_energy[i]]->datamask_modify); } } void ModifyKokkos::min_pushstore() { for (int i = 0; i < n_min_energy; i++) { atomKK->sync(fix[list_min_energy[i]]->execution_space, fix[list_min_energy[i]]->datamask_read); + if (!fix[list_min_energy[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_min_energy[i]]->min_pushstore(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_min_energy[i]]->execution_space, fix[list_min_energy[i]]->datamask_modify); } } void ModifyKokkos::min_popstore() { for (int i = 0; i < n_min_energy; i++) { atomKK->sync(fix[list_min_energy[i]]->execution_space, fix[list_min_energy[i]]->datamask_read); + if (!fix[list_min_energy[i]]->kokkosable) lmp->kokkos->auto_sync = 1; fix[list_min_energy[i]]->min_popstore(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_min_energy[i]]->execution_space, fix[list_min_energy[i]]->datamask_modify); } } /* ---------------------------------------------------------------------- displace extra dof along vector hextra, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::min_step(double alpha, double *hextra) { int ifix,index; index = 0; for (int i = 0; i < n_min_energy; i++) { ifix = list_min_energy[i]; atomKK->sync(fix[ifix]->execution_space,fix[ifix]->datamask_read); + if (!fix[ifix]->kokkosable) lmp->kokkos->auto_sync = 1; fix[ifix]->min_step(alpha,&hextra[index]); index += fix[ifix]->min_dof(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[ifix]->execution_space,fix[ifix]->datamask_modify); } } /* ---------------------------------------------------------------------- compute max allowed step size along vector hextra, only for relevant fixes ------------------------------------------------------------------------- */ double ModifyKokkos::max_alpha(double *hextra) { int ifix,index; double alpha = BIG; index = 0; for (int i = 0; i < n_min_energy; i++) { ifix = list_min_energy[i]; atomKK->sync(fix[ifix]->execution_space,fix[ifix]->datamask_read); + if (!fix[ifix]->kokkosable) lmp->kokkos->auto_sync = 1; double alpha_one = fix[ifix]->max_alpha(&hextra[index]); alpha = MIN(alpha,alpha_one); index += fix[ifix]->min_dof(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[ifix]->execution_space,fix[ifix]->datamask_modify); } return alpha; } /* ---------------------------------------------------------------------- extract extra dof for minimization, only for relevant fixes ------------------------------------------------------------------------- */ int ModifyKokkos::min_dof() { int ndof = 0; for (int i = 0; i < n_min_energy; i++) { atomKK->sync(fix[list_min_energy[i]]->execution_space, fix[list_min_energy[i]]->datamask_read); + if (!fix[list_min_energy[i]]->kokkosable) lmp->kokkos->auto_sync = 1; ndof += fix[list_min_energy[i]]->min_dof(); + lmp->kokkos->auto_sync = 0; atomKK->modified(fix[list_min_energy[i]]->execution_space, fix[list_min_energy[i]]->datamask_modify); } return ndof; } /* ---------------------------------------------------------------------- reset reference state of fix, only for relevant fixes ------------------------------------------------------------------------- */ int ModifyKokkos::min_reset_ref() { int itmp,itmpall; itmpall = 0; for (int i = 0; i < n_min_energy; i++) { atomKK->sync(fix[list_min_energy[i]]->execution_space, fix[list_min_energy[i]]->datamask_read); + if (!fix[list_min_energy[i]]->kokkosable) lmp->kokkos->auto_sync = 1; itmp = fix[list_min_energy[i]]->min_reset_ref(); + lmp->kokkos->auto_sync = 0; if (itmp) itmpall = 1; atomKK->modified(fix[list_min_energy[i]]->execution_space, fix[list_min_energy[i]]->datamask_modify); } return itmpall; } diff --git a/src/KOKKOS/neighbor_kokkos.cpp b/src/KOKKOS/neighbor_kokkos.cpp index c420f34e8..3bb8b0dce 100644 --- a/src/KOKKOS/neighbor_kokkos.cpp +++ b/src/KOKKOS/neighbor_kokkos.cpp @@ -1,613 +1,623 @@ ;/* ---------------------------------------------------------------------- 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 "neighbor_kokkos.h" #include "atom.h" #include "pair.h" #include "fix.h" #include "neigh_request.h" #include "memory.h" #include "update.h" #include "atom_masks.h" #include "error.h" #include "kokkos.h" using namespace LAMMPS_NS; enum{NSQ,BIN,MULTI}; // also in neigh_list.cpp /* ---------------------------------------------------------------------- */ NeighborKokkos::NeighborKokkos(LAMMPS *lmp) : Neighbor(lmp), neighbond_host(lmp),neighbond_device(lmp) { atoms_per_bin = 16; nlist_host = 0; lists_host = NULL; pair_build_host = NULL; stencil_create_host = NULL; nlist_device = 0; lists_device = NULL; pair_build_device = NULL; stencil_create_device = NULL; device_flag = 0; } /* ---------------------------------------------------------------------- */ NeighborKokkos::~NeighborKokkos() { if (!copymode) { memory->destroy_kokkos(k_cutneighsq,cutneighsq); cutneighsq = NULL; for (int i = 0; i < nlist_host; i++) delete lists_host[i]; delete [] lists_host; for (int i = 0; i < nlist_device; i++) delete lists_device[i]; delete [] lists_device; delete [] pair_build_device; delete [] pair_build_host; memory->destroy_kokkos(k_ex_type,ex_type); memory->destroy_kokkos(k_ex1_type,ex1_type); memory->destroy_kokkos(k_ex2_type,ex2_type); memory->destroy_kokkos(k_ex1_group,ex1_group); memory->destroy_kokkos(k_ex2_group,ex2_group); memory->destroy_kokkos(k_ex_mol_group,ex_mol_group); memory->destroy_kokkos(k_ex1_bit,ex1_bit); memory->destroy_kokkos(k_ex2_bit,ex2_bit); memory->destroy_kokkos(k_ex_mol_bit,ex_mol_bit); memory->destroy_kokkos(k_bondlist,bondlist); memory->destroy_kokkos(k_anglelist,anglelist); memory->destroy_kokkos(k_dihedrallist,dihedrallist); memory->destroy_kokkos(k_improperlist,improperlist); } } /* ---------------------------------------------------------------------- */ void NeighborKokkos::init() { atomKK = (AtomKokkos *) atom; Neighbor::init(); } /* ---------------------------------------------------------------------- */ void NeighborKokkos::init_cutneighsq_kokkos(int n) { memory->create_kokkos(k_cutneighsq,cutneighsq,n+1,n+1,"neigh:cutneighsq"); k_cutneighsq.modify(); } /* ---------------------------------------------------------------------- */ int NeighborKokkos::init_lists_kokkos() { int i; for (i = 0; i < nlist_host; i++) delete lists_host[i]; delete [] lists_host; delete [] pair_build_host; delete [] stencil_create_host; nlist_host = 0; for (i = 0; i < nlist_device; i++) delete lists_device[i]; delete [] lists_device; delete [] pair_build_device; delete [] stencil_create_device; nlist_device = 0; nlist = 0; for (i = 0; i < nrequest; i++) { if (requests[i]->kokkos_device) nlist_device++; else if (requests[i]->kokkos_host) nlist_host++; else nlist++; } lists_host = new NeighListKokkos*[nrequest]; pair_build_host = new PairPtrHost[nrequest]; stencil_create_host = new StencilPtrHost[nrequest]; for (i = 0; i < nrequest; i++) { lists_host[i] = NULL; pair_build_host[i] = NULL; stencil_create_host[i] = NULL; } for (i = 0; i < nrequest; i++) { if (!requests[i]->kokkos_host) continue; lists_host[i] = new NeighListKokkos(lmp); lists_host[i]->index = i; lists_host[i]->dnum = requests[i]->dnum; if (requests[i]->pair) { Pair *pair = (Pair *) requests[i]->requestor; pair->init_list(requests[i]->id,lists_host[i]); } if (requests[i]->fix) { Fix *fix = (Fix *) requests[i]->requestor; fix->init_list(requests[i]->id,lists_host[i]); } } lists_device = new NeighListKokkos*[nrequest]; pair_build_device = new PairPtrDevice[nrequest]; stencil_create_device = new StencilPtrDevice[nrequest]; for (i = 0; i < nrequest; i++) { lists_device[i] = NULL; pair_build_device[i] = NULL; stencil_create_device[i] = NULL; } for (i = 0; i < nrequest; i++) { if (!requests[i]->kokkos_device) continue; lists_device[i] = new NeighListKokkos(lmp); lists_device[i]->index = i; lists_device[i]->dnum = requests[i]->dnum; if (requests[i]->pair) { Pair *pair = (Pair *) requests[i]->requestor; pair->init_list(requests[i]->id,lists_device[i]); } if (requests[i]->fix) { Fix *fix = (Fix *) requests[i]->requestor; fix->init_list(requests[i]->id,lists_device[i]); } } // 1st time allocation of xhold if (dist_check) xhold = DAT::tdual_x_array("neigh:xhold",maxhold); // return # of non-Kokkos lists return nlist; } /* ---------------------------------------------------------------------- */ void NeighborKokkos::init_list_flags1_kokkos(int i) { if (lists_host[i]) { lists_host[i]->buildflag = 1; if (pair_build_host[i] == NULL) lists_host[i]->buildflag = 0; if (requests[i]->occasional) lists_host[i]->buildflag = 0; lists_host[i]->growflag = 1; if (requests[i]->copy) lists_host[i]->growflag = 0; lists_host[i]->stencilflag = 1; if (style == NSQ) lists_host[i]->stencilflag = 0; if (stencil_create[i] == NULL) lists_host[i]->stencilflag = 0; lists_host[i]->ghostflag = 0; if (requests[i]->ghost) lists_host[i]->ghostflag = 1; if (requests[i]->ghost && !requests[i]->occasional) anyghostlist = 1; } if (lists_device[i]) { lists_device[i]->buildflag = 1; if (pair_build_device[i] == NULL) lists_device[i]->buildflag = 0; if (requests[i]->occasional) lists_device[i]->buildflag = 0; lists_device[i]->growflag = 1; if (requests[i]->copy) lists_device[i]->growflag = 0; lists_device[i]->stencilflag = 1; if (style == NSQ) lists_device[i]->stencilflag = 0; if (stencil_create[i] == NULL) lists_device[i]->stencilflag = 0; lists_device[i]->ghostflag = 0; if (requests[i]->ghost) lists_device[i]->ghostflag = 1; if (requests[i]->ghost && !requests[i]->occasional) anyghostlist = 1; } } /* ---------------------------------------------------------------------- */ void NeighborKokkos::init_list_flags2_kokkos(int i) { if (lists_host[i]) { if (lists_host[i]->buildflag) blist[nblist++] = i; if (lists_host[i]->growflag && requests[i]->occasional == 0) glist[nglist++] = i; if (lists_host[i]->stencilflag && requests[i]->occasional == 0) slist[nslist++] = i; } if (lists_device[i]) { if (lists_device[i]->buildflag) blist[nblist++] = i; if (lists_device[i]->growflag && requests[i]->occasional == 0) glist[nglist++] = i; if (lists_device[i]->stencilflag && requests[i]->occasional == 0) slist[nslist++] = i; } } /* ---------------------------------------------------------------------- */ void NeighborKokkos::init_list_grow_kokkos(int i) { if (lists_host[i]!=NULL && lists_host[i]->growflag) lists_host[i]->grow(maxatom); if (lists_device[i]!=NULL && lists_device[i]->growflag) lists_device[i]->grow(maxatom); } /* ---------------------------------------------------------------------- */ void NeighborKokkos::init_ex_type_kokkos(int n) { memory->create_kokkos(k_ex_type,ex_type,n+1,n+1,"neigh:ex_type"); k_ex_type.modify(); } /* ---------------------------------------------------------------------- */ void NeighborKokkos::init_ex_bit_kokkos() { memory->create_kokkos(k_ex1_bit, ex1_bit, nex_group, "neigh:ex1_bit"); k_ex1_bit.modify(); memory->create_kokkos(k_ex2_bit, ex2_bit, nex_group, "neigh:ex2_bit"); k_ex2_bit.modify(); } /* ---------------------------------------------------------------------- */ void NeighborKokkos::init_ex_mol_bit_kokkos() { memory->create_kokkos(k_ex_mol_bit, ex_mol_bit, nex_mol, "neigh:ex_mol_bit"); k_ex_mol_bit.modify(); } /* ---------------------------------------------------------------------- */ void NeighborKokkos::choose_build(int index, NeighRequest *rq) { if (rq->kokkos_host != 0) { PairPtrHost pb = NULL; if (rq->ghost) { if (rq->full) { if (rq->full_cluster) pb = &NeighborKokkos::full_bin_cluster_kokkos; else pb = &NeighborKokkos::full_bin_kokkos; } else if (rq->half) pb = &NeighborKokkos::full_bin_kokkos; } else { if (rq->full) { if (rq->full_cluster) pb = &NeighborKokkos::full_bin_cluster_kokkos; else pb = &NeighborKokkos::full_bin_kokkos; } else if (rq->half) pb = &NeighborKokkos::full_bin_kokkos; } pair_build_host[index] = pb; } if (rq->kokkos_device != 0) { PairPtrDevice pb = NULL; if (rq->ghost) { if (rq->full) { if (rq->full_cluster) pb = &NeighborKokkos::full_bin_cluster_kokkos; else pb = &NeighborKokkos::full_bin_kokkos; } else if (rq->half) pb = &NeighborKokkos::full_bin_kokkos; } else { if (rq->full) { if (rq->full_cluster) pb = &NeighborKokkos::full_bin_cluster_kokkos; else pb = &NeighborKokkos::full_bin_kokkos; } else if (rq->half) pb = &NeighborKokkos::full_bin_kokkos; } pair_build_device[index] = pb; return; } Neighbor::choose_build(index,rq); } /* ---------------------------------------------------------------------- if any atom moved trigger distance (half of neighbor skin) return 1 shrink trigger distance if box size has changed conservative shrink procedure: compute distance each of 8 corners of box has moved since last reneighbor reduce skin distance by sum of 2 largest of the 8 values new trigger = 1/2 of reduced skin distance for orthogonal box, only need 2 lo/hi corners for triclinic, need all 8 corners since deformations can displace all 8 ------------------------------------------------------------------------- */ int NeighborKokkos::check_distance() { if (nlist_device) check_distance_kokkos(); else check_distance_kokkos(); } template int NeighborKokkos::check_distance_kokkos() { typedef DeviceType device_type; double delx,dely,delz,rsq; double delta,delta1,delta2; if (boxcheck) { if (triclinic == 0) { delx = bboxlo[0] - boxlo_hold[0]; dely = bboxlo[1] - boxlo_hold[1]; delz = bboxlo[2] - boxlo_hold[2]; delta1 = sqrt(delx*delx + dely*dely + delz*delz); delx = bboxhi[0] - boxhi_hold[0]; dely = bboxhi[1] - boxhi_hold[1]; delz = bboxhi[2] - boxhi_hold[2]; delta2 = sqrt(delx*delx + dely*dely + delz*delz); delta = 0.5 * (skin - (delta1+delta2)); deltasq = delta*delta; } else { domain->box_corners(); delta1 = delta2 = 0.0; for (int i = 0; i < 8; i++) { delx = corners[i][0] - corners_hold[i][0]; dely = corners[i][1] - corners_hold[i][1]; delz = corners[i][2] - corners_hold[i][2]; delta = sqrt(delx*delx + dely*dely + delz*delz); if (delta > delta1) delta1 = delta; else if (delta > delta2) delta2 = delta; } delta = 0.5 * (skin - (delta1+delta2)); deltasq = delta*delta; } } else deltasq = triggersq; atomKK->sync(ExecutionSpaceFromDevice::space,X_MASK); x = atomKK->k_x; xhold.sync(); int nlocal = atom->nlocal; if (includegroup) nlocal = atom->nfirst; int flag = 0; copymode = 1; Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,nlocal),*this,flag); DeviceType::fence(); copymode = 0; int flagall; MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_MAX,world); if (flagall && ago == MAX(every,delay)) ndanger++; return flagall; } template KOKKOS_INLINE_FUNCTION void NeighborKokkos::operator()(TagNeighborCheckDistance, const int &i, int &flag) const { typedef DeviceType device_type; const X_FLOAT delx = x.view()(i,0) - xhold.view()(i,0); const X_FLOAT dely = x.view()(i,1) - xhold.view()(i,1); const X_FLOAT delz = x.view()(i,2) - xhold.view()(i,2); const X_FLOAT rsq = delx*delx + dely*dely + delz*delz; if (rsq > deltasq) flag = 1; } /* ---------------------------------------------------------------------- build perpetuals neighbor lists called at setup and every few timesteps during run or minimization topology lists also built if topoflag = 1, USER-CUDA calls with topoflag = 0 ------------------------------------------------------------------------- */ void NeighborKokkos::build(int topoflag) { if (nlist_device) build_kokkos(topoflag); else build_kokkos(topoflag); } template void NeighborKokkos::build_kokkos(int topoflag) { typedef DeviceType device_type; int i; ago = 0; ncalls++; lastcall = update->ntimestep; // store current atom positions and box size if needed if (dist_check) { atomKK->sync(ExecutionSpaceFromDevice::space,X_MASK); x = atomKK->k_x; int nlocal = atom->nlocal; if (includegroup) nlocal = atom->nfirst; int maxhold_kokkos = xhold.view().dimension_0(); if (atom->nmax > maxhold || maxhold_kokkos < maxhold) { maxhold = atom->nmax; xhold = DAT::tdual_x_array("neigh:xhold",maxhold); } copymode = 1; Kokkos::parallel_for(Kokkos::RangePolicy >(0,nlocal),*this); DeviceType::fence(); copymode = 0; xhold.modify(); if (boxcheck) { if (triclinic == 0) { boxlo_hold[0] = bboxlo[0]; boxlo_hold[1] = bboxlo[1]; boxlo_hold[2] = bboxlo[2]; boxhi_hold[0] = bboxhi[0]; boxhi_hold[1] = bboxhi[1]; boxhi_hold[2] = bboxhi[2]; } else { domain->box_corners(); corners = domain->corners; for (i = 0; i < 8; i++) { corners_hold[i][0] = corners[i][0]; corners_hold[i][1] = corners[i][1]; corners_hold[i][2] = corners[i][2]; } } } } // if any lists store neighbors of ghosts: // invoke grow() if nlocal+nghost exceeds previous list size // else only invoke grow() if nlocal exceeds previous list size // only for lists with growflag set and which are perpetual (glist) if (anyghostlist && atom->nmax > maxatom) { maxatom = atom->nmax; for (i = 0; i < nglist; i++) if (lists[glist[i]]) lists[glist[i]]->grow(maxatom); else init_list_grow_kokkos(glist[i]); } else if (atom->nmax > maxatom) { maxatom = atom->nmax; for (i = 0; i < nglist; i++) if (lists[glist[i]]) lists[glist[i]]->grow(maxatom); else init_list_grow_kokkos(glist[i]); } // extend atom bin list if necessary if (style != NSQ && atom->nmax > maxbin) { maxbin = atom->nmax; memory->destroy(bins); memory->create(bins,maxbin,"bins"); } // check that using special bond flags will not overflow neigh lists if (atom->nlocal+atom->nghost > NEIGHMASK) error->one(FLERR,"Too many local+ghost atoms for neighbor list"); // invoke building of pair and molecular topology neighbor lists // only for pairwise lists with buildflag set // blist is for standard neigh lists, otherwise is a Kokkos list for (i = 0; i < nblist; i++) { if (lists[blist[i]]) { atomKK->sync(Host,ALL_MASK); (this->*pair_build[blist[i]])(lists[blist[i]]); } else { if (lists_host[blist[i]]) (this->*pair_build_host[blist[i]])(lists_host[blist[i]]); else if (lists_device[blist[i]]) (this->*pair_build_device[blist[i]])(lists_device[blist[i]]); } } if (atom->molecular && topoflag) build_topology_kokkos(); } template KOKKOS_INLINE_FUNCTION void NeighborKokkos::operator()(TagNeighborXhold, const int &i) const { typedef DeviceType device_type; xhold.view()(i,0) = x.view()(i,0); xhold.view()(i,1) = x.view()(i,1); xhold.view()(i,2) = x.view()(i,2); } /* ---------------------------------------------------------------------- */ void NeighborKokkos::setup_bins_kokkos(int i) { if (lists_host[slist[i]]) { lists_host[slist[i]]->stencil_allocate(smax,style); (this->*stencil_create[slist[i]])(lists_host[slist[i]],sx,sy,sz); } else if (lists_device[slist[i]]) { lists_device[slist[i]]->stencil_allocate(smax,style); (this->*stencil_create[slist[i]])(lists_device[slist[i]],sx,sy,sz); } //if (i < nslist-1) return; // this won't work if a non-kokkos neighbor list is last if (maxhead > k_bins.d_view.dimension_0()) { k_bins = DAT::tdual_int_2d("Neighbor::d_bins",maxhead,atoms_per_bin); k_bincount = DAT::tdual_int_1d("Neighbor::d_bincount",maxhead); } } /* ---------------------------------------------------------------------- */ void NeighborKokkos::modify_ex_type_grow_kokkos(){ memory->grow_kokkos(k_ex1_type,ex1_type,maxex_type,"neigh:ex1_type"); k_ex1_type.modify(); memory->grow_kokkos(k_ex2_type,ex2_type,maxex_type,"neigh:ex2_type"); k_ex2_type.modify(); } /* ---------------------------------------------------------------------- */ void NeighborKokkos::modify_ex_group_grow_kokkos(){ memory->grow_kokkos(k_ex1_group,ex1_group,maxex_group,"neigh:ex1_group"); k_ex1_group.modify(); memory->grow_kokkos(k_ex2_group,ex2_group,maxex_group,"neigh:ex2_group"); k_ex2_group.modify(); } /* ---------------------------------------------------------------------- */ void NeighborKokkos::modify_mol_group_grow_kokkos(){ memory->grow_kokkos(k_ex_mol_group,ex_mol_group,maxex_mol,"neigh:ex_mol_group"); k_ex_mol_group.modify(); } /* ---------------------------------------------------------------------- */ void NeighborKokkos::init_topology_kokkos() { if (nlist_device) { neighbond_device.init_topology_kk(); } else { neighbond_host.init_topology_kk(); } } /* ---------------------------------------------------------------------- build all topology neighbor lists every few timesteps normally built with pair lists, but USER-CUDA separates them ------------------------------------------------------------------------- */ void NeighborKokkos::build_topology_kokkos() { if (nlist_device) { neighbond_device.build_topology_kk(); k_bondlist = neighbond_device.k_bondlist; k_anglelist = neighbond_device.k_anglelist; k_dihedrallist = neighbond_device.k_dihedrallist; k_improperlist = neighbond_device.k_improperlist; + k_bondlist.sync(); + k_anglelist.sync(); + k_dihedrallist.sync(); + k_improperlist.sync(); + k_bondlist.modify(); k_anglelist.modify(); k_dihedrallist.modify(); k_improperlist.modify(); } else { neighbond_host.build_topology_kk(); k_bondlist = neighbond_host.k_bondlist; k_anglelist = neighbond_host.k_anglelist; k_dihedrallist = neighbond_host.k_dihedrallist; k_improperlist = neighbond_host.k_improperlist; + k_bondlist.sync(); + k_anglelist.sync(); + k_dihedrallist.sync(); + k_improperlist.sync(); + k_bondlist.modify(); k_anglelist.modify(); k_dihedrallist.modify(); k_improperlist.modify(); } } // include to trigger instantiation of templated functions #include "neigh_full_kokkos.h" diff --git a/src/KOKKOS/pair_reax_c_kokkos.h b/src/KOKKOS/pair_reax_c_kokkos.h index a6192ed12..8c07ee2a0 100644 --- a/src/KOKKOS/pair_reax_c_kokkos.h +++ b/src/KOKKOS/pair_reax_c_kokkos.h @@ -1,430 +1,430 @@ /* -*- 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. ------------------------------------------------------------------------- */ #ifdef PAIR_CLASS PairStyle(reax/c/kk,PairReaxCKokkos) PairStyle(reax/c/kk/device,PairReaxCKokkos) PairStyle(reax/c/kk/host,PairReaxCKokkos) #else #ifndef LMP_PAIR_REAXC_KOKKOS_H #define LMP_PAIR_REAXC_KOKKOS_H -#include "stdio.h" +#include #include "pair_kokkos.h" #include "pair_reax_c.h" #include "neigh_list_kokkos.h" #include "reaxc_types.h" #define C_ele 332.06371 #define SMALL 0.0001 #define KCALpMOL_to_EV 23.02 #define HB_THRESHOLD 1e-2 // 0.01 #define MAX_BONDS 30 #define SQR(x) ((x)*(x)) namespace LAMMPS_NS { typedef Kokkos::DualView tdual_LR_data_1d; typedef typename tdual_LR_data_1d::t_dev t_LR_data_1d; typedef Kokkos::DualView tdual_cubic_spline_coef_1d; typedef typename tdual_cubic_spline_coef_1d::t_dev t_cubic_spline_coef_1d; struct LR_lookup_table_kk { double xmin, xmax; int n; double dx, inv_dx; double a; double m; double c; t_LR_data_1d d_y; t_cubic_spline_coef_1d d_H; t_cubic_spline_coef_1d d_vdW, d_CEvd; t_cubic_spline_coef_1d d_ele, d_CEclmb; }; template struct PairReaxComputePolar{}; template struct PairReaxComputeLJCoulomb{}; template struct PairReaxComputeTabulatedLJCoulomb{}; struct PairReaxBuildListsFull{}; template struct PairReaxBuildListsHalf{}; template struct PairReaxBuildListsHalf_LessAtomics{}; struct PairReaxZero{}; struct PairReaxZeroEAtom{}; struct PairReaxZeroVAtom{}; struct PairReaxBondOrder1{}; struct PairReaxBondOrder1_LessAtomics{}; struct PairReaxBondOrder2{}; struct PairReaxBondOrder3{}; template struct PairReaxUpdateBond{}; template struct PairReaxComputeBond1{}; template struct PairReaxComputeBond2{}; template struct PairReaxComputeMulti1{}; template struct PairReaxComputeMulti2{}; template struct PairReaxComputeAngular{}; template struct PairReaxComputeTorsion{}; template struct PairReaxComputeHydrogen{}; template class PairReaxCKokkos : public PairReaxC { public: enum {EnabledNeighFlags=FULL|HALF|HALFTHREAD}; enum {COUL_FLAG=1}; typedef DeviceType device_type; typedef ArrayTypes AT; typedef EV_FLOAT_REAX value_type; PairReaxCKokkos(class LAMMPS *); virtual ~PairReaxCKokkos(); void ev_setup(int, int); void compute(int, int); void *extract(const char *, int &); void init_style(); double memory_usage(); template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputePolar, const int&, EV_FLOAT_REAX&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputePolar, const int&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputeLJCoulomb, const int&, EV_FLOAT_REAX&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputeLJCoulomb, const int&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputeTabulatedLJCoulomb, const int&, EV_FLOAT_REAX&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputeTabulatedLJCoulomb, const int&) const; KOKKOS_INLINE_FUNCTION void operator()(PairReaxBuildListsFull, const int&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxBuildListsHalf, const int&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxBuildListsHalf_LessAtomics, const int&) const; KOKKOS_INLINE_FUNCTION void operator()(PairReaxZero, const int&) const; KOKKOS_INLINE_FUNCTION void operator()(PairReaxZeroEAtom, const int&) const; KOKKOS_INLINE_FUNCTION void operator()(PairReaxZeroVAtom, const int&) const; KOKKOS_INLINE_FUNCTION void operator()(PairReaxBondOrder1, const int&) const; KOKKOS_INLINE_FUNCTION void operator()(PairReaxBondOrder1_LessAtomics, const int&) const; KOKKOS_INLINE_FUNCTION void operator()(PairReaxBondOrder2, const int&) const; KOKKOS_INLINE_FUNCTION void operator()(PairReaxBondOrder3, const int&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxUpdateBond, const int&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputeBond1, const int&, EV_FLOAT_REAX&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputeBond1, const int&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputeBond2, const int&, EV_FLOAT_REAX&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputeBond2, const int&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputeMulti1, const int&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputeMulti2, const int&, EV_FLOAT_REAX&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputeMulti2, const int&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputeAngular, const int&, EV_FLOAT_REAX&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputeAngular, const int&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputeTorsion, const int&, EV_FLOAT_REAX&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputeTorsion, const int&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputeHydrogen, const int&, EV_FLOAT_REAX&) const; template KOKKOS_INLINE_FUNCTION void operator()(PairReaxComputeHydrogen, const int&) const; struct params_sing{ KOKKOS_INLINE_FUNCTION params_sing(){mass=0;chi=0;eta=0;r_s=0;r_pi=0;r_pi2=0;valency=0;valency_val=0;valency_e=0;valency_boc=0;nlp_opt=0; p_lp2=0;p_ovun2=0;p_ovun5=0;p_val3=0;p_val5=0;p_hbond=0;}; KOKKOS_INLINE_FUNCTION params_sing(int i){mass=0;chi=0;eta=0;r_s=0;r_pi=0;r_pi2=0;valency=0;valency_val=0;valency_e=0;valency_boc=0;nlp_opt=0; p_lp2=0;p_ovun2=0;p_ovun5=0;p_val3=0;p_val5=0;p_hbond=0;}; F_FLOAT mass,chi,eta,r_s,r_pi,r_pi2,valency,valency_val,valency_e,valency_boc,nlp_opt, p_lp2,p_ovun2,p_ovun5, p_val3, p_val5, p_hbond; }; struct params_twbp{ KOKKOS_INLINE_FUNCTION params_twbp(){gamma=0;gamma_w=0;alpha=0;r_vdw=0;epsilon=0;acore=0;ecore=0;rcore=0;lgre=0;lgcij=0; r_s=0;r_pi=0;r_pi2=0;p_bo1=0;p_bo2=0;p_bo3=0;p_bo4=0;p_bo5=0;p_bo6=0;ovc=0;v13cor=0; p_boc3=0;p_boc4=0;p_boc5=0;p_be1=0,p_be2=0,De_s=0,De_p=0;De_pp=0; p_ovun1=0;}; KOKKOS_INLINE_FUNCTION params_twbp(int i){gamma=0;gamma_w=0;alpha=0;r_vdw=0;epsilon=0;acore=0;ecore=0;rcore=0;lgre=0;lgcij=0; r_s=0;r_pi=0;r_pi2=0;p_bo1=0;p_bo2=0;p_bo3=0;p_bo4=0;p_bo5=0;p_bo6=0;ovc=0;v13cor=0; p_boc3=0;p_boc4=0;p_boc5=0;p_be1=0,p_be2=0,De_s=0,De_p=0;De_pp=0; p_ovun1=0;}; F_FLOAT gamma,gamma_w,alpha,r_vdw,epsilon,acore,ecore,rcore,lgre,lgcij, r_s,r_pi,r_pi2,p_bo1,p_bo2,p_bo3,p_bo4,p_bo5,p_bo6,ovc,v13cor, p_boc3,p_boc4,p_boc5,p_be1,p_be2,De_s,De_p,De_pp, p_ovun1; }; struct params_thbp{ KOKKOS_INLINE_FUNCTION params_thbp(){cnt=0;theta_00=0;p_val1=0;p_val2=0;p_val4=0;p_val7=0;p_pen1=0;p_coa1=0;}; KOKKOS_INLINE_FUNCTION params_thbp(int i){cnt=0;theta_00=0;p_val1=0;p_val2=0;p_val4=0;p_val7=0;p_pen1=0;p_coa1=0;}; F_FLOAT cnt, theta_00, p_val1, p_val2, p_val4, p_val7, p_pen1, p_coa1; }; struct params_fbp{ KOKKOS_INLINE_FUNCTION params_fbp(){p_tor1=0;p_cot1=0;V1=0;V2=0;V3=0;}; KOKKOS_INLINE_FUNCTION params_fbp(int i){p_tor1=0;p_cot1=0;V1=0;V2=0;V3=0;}; F_FLOAT p_tor1, p_cot1, V1, V2, V3; }; struct params_hbp{ KOKKOS_INLINE_FUNCTION params_hbp(){p_hb1=0;p_hb2=0;p_hb3=0;r0_hb=0;}; KOKKOS_INLINE_FUNCTION params_hbp(int i){p_hb1=0;p_hb2=0;p_hb3=0;r0_hb=0;}; F_FLOAT p_hb1, p_hb2, p_hb3, r0_hb; }; template KOKKOS_INLINE_FUNCTION void ev_tally(EV_FLOAT_REAX &ev, const int &i, const int &j, const F_FLOAT &epair, const F_FLOAT &fpair, const F_FLOAT &delx, const F_FLOAT &dely, const F_FLOAT &delz) const; template KOKKOS_INLINE_FUNCTION void e_tally(EV_FLOAT_REAX &ev, const int &i, const int &j, const F_FLOAT &epair) const; template KOKKOS_INLINE_FUNCTION void e_tally_single(EV_FLOAT_REAX &ev, const int &i, const F_FLOAT &epair) const; template KOKKOS_INLINE_FUNCTION void v_tally(EV_FLOAT_REAX &ev, const int &i, F_FLOAT *fi, F_FLOAT *drij) const; template KOKKOS_INLINE_FUNCTION void v_tally3(EV_FLOAT_REAX &ev, const int &i, const int &j, const int &k, F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *drij, F_FLOAT *drik) const; KOKKOS_INLINE_FUNCTION void v_tally3_atom(EV_FLOAT_REAX &ev, const int &i, const int &j, const int &k, F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *drji, F_FLOAT *drjk) const; template KOKKOS_INLINE_FUNCTION void v_tally4(EV_FLOAT_REAX &ev, const int &i, const int &j, const int &k, const int &l, F_FLOAT *fi, F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *dril, F_FLOAT *drjl, F_FLOAT *drkl) const; protected: void cleanup_copy(); void allocate(); void allocate_array(); void setup(); void init_md(); int Init_Lookup_Tables(); void Deallocate_Lookup_Tables(); void LR_vdW_Coulomb( int i, int j, double r_ij, LR_data *lr ); typedef Kokkos::DualView tdual_int_1d; Kokkos::DualView k_params_sing; typename Kokkos::DualView::t_dev_const paramssing; typedef Kokkos::DualView tdual_int_2d; Kokkos::DualView k_params_twbp; typename Kokkos::DualView::t_dev_const paramstwbp; typedef Kokkos::DualView tdual_int_3d; Kokkos::DualView k_params_thbp; typename Kokkos::DualView::t_dev_const paramsthbp; Kokkos::DualView k_params_hbp; typename Kokkos::DualView::t_dev_const paramshbp; typedef Kokkos::DualView tdual_int_4d; Kokkos::DualView k_params_fbp; typename Kokkos::DualView::t_dev_const paramsfbp; typename AT::t_x_array_randomread x; typename AT::t_f_array f; typename AT::t_int_1d_randomread type; typename AT::t_tagint_1d tag; typename AT::t_float_1d_randomread q; DAT::tdual_efloat_1d k_eatom; typename AT::t_efloat_1d v_eatom; DAT::tdual_virial_array k_vatom; DAT::t_virial_array d_vatom; typename AT::t_virial_array v_vatom; HAT::t_virial_array h_vatom; DAT::tdual_float_1d k_tap; DAT::t_float_1d d_tap; HAT::t_float_1d h_tap; typename AT::t_float_1d d_bo_rij, d_hb_rsq, d_Deltap, d_Deltap_boc, d_total_bo; typename AT::t_float_1d d_Delta, d_Delta_boc, d_Delta_lp, d_dDelta_lp, d_Delta_lp_temp, d_CdDelta; typename AT::t_ffloat_2d_dl d_BO, d_BO_s, d_BO_pi, d_BO_pi2, d_dBOp; typename AT::t_ffloat_2d_dl d_dln_BOp_pix, d_dln_BOp_piy, d_dln_BOp_piz; typename AT::t_ffloat_2d_dl d_dln_BOp_pi2x, d_dln_BOp_pi2y, d_dln_BOp_pi2z; typename AT::t_ffloat_2d_dl d_C1dbo, d_C2dbo, d_C3dbo; typename AT::t_ffloat_2d_dl d_C1dbopi, d_C2dbopi, d_C3dbopi, d_C4dbopi; typename AT::t_ffloat_2d_dl d_C1dbopi2, d_C2dbopi2, d_C3dbopi2, d_C4dbopi2; typename AT::t_ffloat_2d_dl d_Cdbo, d_Cdbopi, d_Cdbopi2, d_dDeltap_self; typedef Kokkos::DualView tdual_ffloat_2d_n7; typedef typename tdual_ffloat_2d_n7::t_dev_const_randomread t_ffloat_2d_n7_randomread; typedef typename tdual_ffloat_2d_n7::t_host t_host_ffloat_2d_n7; typename ArrayTypes::t_neighbors_2d d_neighbors; typename ArrayTypes::t_int_1d_randomread d_ilist; typename ArrayTypes::t_int_1d_randomread d_numneigh; typename AT::t_int_1d d_bo_first, d_bo_num, d_bo_list, d_hb_first, d_hb_num, d_hb_list; DAT::tdual_int_scalar k_resize_bo, k_resize_hb; typename AT::t_int_scalar d_resize_bo, d_resize_hb; typename AT::t_ffloat_2d_dl d_sum_ovun; typename AT::t_ffloat_2d_dl d_dBOpx, d_dBOpy, d_dBOpz; class AtomKokkos *atomKK; int neighflag,newton_pair, maxnumneigh, maxhb, maxbo; int nlocal,nall,eflag,vflag; F_FLOAT cut_nbsq, cut_hbsq, cut_bosq, bo_cut, thb_cut, thb_cutsq; int vdwflag, lgflag; F_FLOAT gp[39], p_boc1, p_boc2; friend void pair_virial_fdotr_compute(PairReaxCKokkos*); int bocnt,hbcnt; typedef Kokkos::DualView tdual_LR_lookup_table_kk_2d; typedef typename tdual_LR_lookup_table_kk_2d::t_dev t_LR_lookup_table_kk_2d; tdual_LR_lookup_table_kk_2d k_LR; t_LR_lookup_table_kk_2d d_LR; }; } #endif #endif /* ERROR/WARNING messages: */ diff --git a/src/KOKKOS/verlet_kokkos.cpp b/src/KOKKOS/verlet_kokkos.cpp index f225249d5..20c403527 100644 --- a/src/KOKKOS/verlet_kokkos.cpp +++ b/src/KOKKOS/verlet_kokkos.cpp @@ -1,612 +1,624 @@ /* ---------------------------------------------------------------------- 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 #include "verlet_kokkos.h" #include "neighbor.h" #include "domain.h" #include "comm.h" #include "atom.h" #include "atom_kokkos.h" #include "atom_masks.h" #include "force.h" #include "pair.h" #include "bond.h" #include "angle.h" #include "dihedral.h" #include "improper.h" #include "kspace.h" #include "output.h" #include "update.h" #include "modify.h" #include "compute.h" #include "fix.h" #include "timer.h" #include "memory.h" #include "error.h" #include using namespace LAMMPS_NS; template struct ForceAdder { ViewA a; ViewB b; ForceAdder(const ViewA& a_, const ViewB& b_):a(a_),b(b_) {} KOKKOS_INLINE_FUNCTION void operator() (const int& i) const { a(i,0) += b(i,0); a(i,1) += b(i,1); a(i,2) += b(i,2); } }; /* ---------------------------------------------------------------------- */ VerletKokkos::VerletKokkos(LAMMPS *lmp, int narg, char **arg) : Verlet(lmp, narg, arg) { atomKK = (AtomKokkos *) atom; } /* ---------------------------------------------------------------------- setup before run ------------------------------------------------------------------------- */ void VerletKokkos::setup() { if (comm->me == 0 && screen) { fprintf(screen,"Setting up Verlet run ...\n"); fprintf(screen," Unit style : %s\n", update->unit_style); fprintf(screen," Current step : " BIGINT_FORMAT "\n", update->ntimestep); fprintf(screen," Time step : %g\n", update->dt); timer->print_timeout(screen); } update->setupflag = 1; + lmp->kokkos->auto_sync = 0; // setup domain, communication and neighboring // acquire ghosts // build neighbor lists + atomKK->sync(Host,ALL_MASK); atomKK->modified(Host,ALL_MASK); atomKK->setup(); modify->setup_pre_exchange(); // debug atomKK->sync(Host,ALL_MASK); atomKK->modified(Host,ALL_MASK); if (triclinic) domain->x2lamda(atomKK->nlocal); domain->pbc(); atomKK->sync(Host,ALL_MASK); domain->reset_box(); comm->setup(); if (neighbor->style) neighbor->setup_bins(); comm->exchange(); if (atomKK->sortfreq > 0) atomKK->sort(); comm->borders(); if (triclinic) domain->lamda2x(atomKK->nlocal+atomKK->nghost); atomKK->sync(Host,ALL_MASK); domain->image_check(); domain->box_too_small_check(); modify->setup_pre_neighbor(); atomKK->modified(Host,ALL_MASK); neighbor->build(); neighbor->ncalls = 0; // compute all forces ev_set(update->ntimestep); force_clear(); modify->setup_pre_force(vflag); if (pair_compute_flag) { atomKK->sync(force->pair->execution_space,force->pair->datamask_read); - atomKK->modified(force->pair->execution_space,force->pair->datamask_modify); force->pair->compute(eflag,vflag); + atomKK->modified(force->pair->execution_space,force->pair->datamask_modify); timer->stamp(Timer::PAIR); } else if (force->pair) force->pair->compute_dummy(eflag,vflag); if (atomKK->molecular) { if (force->bond) { atomKK->sync(force->bond->execution_space,force->bond->datamask_read); - atomKK->modified(force->bond->execution_space,force->bond->datamask_modify); force->bond->compute(eflag,vflag); + atomKK->modified(force->bond->execution_space,force->bond->datamask_modify); } if (force->angle) { atomKK->sync(force->angle->execution_space,force->angle->datamask_read); - atomKK->modified(force->angle->execution_space,force->angle->datamask_modify); force->angle->compute(eflag,vflag); + atomKK->modified(force->angle->execution_space,force->angle->datamask_modify); } if (force->dihedral) { atomKK->sync(force->dihedral->execution_space,force->dihedral->datamask_read); - atomKK->modified(force->dihedral->execution_space,force->dihedral->datamask_modify); force->dihedral->compute(eflag,vflag); + atomKK->modified(force->dihedral->execution_space,force->dihedral->datamask_modify); } if (force->improper) { atomKK->sync(force->improper->execution_space,force->improper->datamask_read); - atomKK->modified(force->improper->execution_space,force->improper->datamask_modify); force->improper->compute(eflag,vflag); + atomKK->modified(force->improper->execution_space,force->improper->datamask_modify); } timer->stamp(Timer::BOND); } if(force->kspace) { force->kspace->setup(); if (kspace_compute_flag) { atomKK->sync(force->kspace->execution_space,force->kspace->datamask_read); - atomKK->modified(force->kspace->execution_space,force->kspace->datamask_modify); force->kspace->compute(eflag,vflag); + atomKK->modified(force->kspace->execution_space,force->kspace->datamask_modify); timer->stamp(Timer::KSPACE); } else force->kspace->compute_dummy(eflag,vflag); } - if (force->newton) comm->reverse_comm(); modify->setup(vflag); output->setup(); - update->setupflag = 0; + lmp->kokkos->auto_sync = 0; + update->setupflag = 1; } /* ---------------------------------------------------------------------- setup without output flag = 0 = just force calculation flag = 1 = reneighbor and force calculation ------------------------------------------------------------------------- */ void VerletKokkos::setup_minimal(int flag) { update->setupflag = 1; + lmp->kokkos->auto_sync = 0; // setup domain, communication and neighboring // acquire ghosts // build neighbor lists if (flag) { + atomKK->sync(Host,ALL_MASK); atomKK->modified(Host,ALL_MASK); modify->setup_pre_exchange(); // debug atomKK->sync(Host,ALL_MASK); atomKK->modified(Host,ALL_MASK); if (triclinic) domain->x2lamda(atomKK->nlocal); domain->pbc(); atomKK->sync(Host,ALL_MASK); domain->reset_box(); comm->setup(); if (neighbor->style) neighbor->setup_bins(); comm->exchange(); comm->borders(); if (triclinic) domain->lamda2x(atomKK->nlocal+atomKK->nghost); atomKK->sync(Host,ALL_MASK); domain->image_check(); domain->box_too_small_check(); modify->setup_pre_neighbor(); atomKK->modified(Host,ALL_MASK); neighbor->build(); neighbor->ncalls = 0; } // compute all forces ev_set(update->ntimestep); force_clear(); modify->setup_pre_force(vflag); if (pair_compute_flag) { atomKK->sync(force->pair->execution_space,force->pair->datamask_read); - atomKK->modified(force->pair->execution_space,force->pair->datamask_modify); force->pair->compute(eflag,vflag); + atomKK->modified(force->pair->execution_space,force->pair->datamask_modify); timer->stamp(Timer::PAIR); } else if (force->pair) force->pair->compute_dummy(eflag,vflag); if (atomKK->molecular) { if (force->bond) { atomKK->sync(force->bond->execution_space,force->bond->datamask_read); - atomKK->modified(force->bond->execution_space,force->bond->datamask_modify); force->bond->compute(eflag,vflag); + atomKK->modified(force->bond->execution_space,force->bond->datamask_modify); } if (force->angle) { atomKK->sync(force->angle->execution_space,force->angle->datamask_read); - atomKK->modified(force->angle->execution_space,force->angle->datamask_modify); force->angle->compute(eflag,vflag); + atomKK->modified(force->angle->execution_space,force->angle->datamask_modify); } if (force->dihedral) { atomKK->sync(force->dihedral->execution_space,force->dihedral->datamask_read); - atomKK->modified(force->dihedral->execution_space,force->dihedral->datamask_modify); force->dihedral->compute(eflag,vflag); + atomKK->modified(force->dihedral->execution_space,force->dihedral->datamask_modify); } if (force->improper) { atomKK->sync(force->improper->execution_space,force->improper->datamask_read); - atomKK->modified(force->improper->execution_space,force->improper->datamask_modify); force->improper->compute(eflag,vflag); + atomKK->modified(force->improper->execution_space,force->improper->datamask_modify); } timer->stamp(Timer::BOND); } if(force->kspace) { force->kspace->setup(); if (kspace_compute_flag) { atomKK->sync(force->kspace->execution_space,force->kspace->datamask_read); - atomKK->modified(force->kspace->execution_space,force->kspace->datamask_modify); force->kspace->compute(eflag,vflag); + atomKK->modified(force->kspace->execution_space,force->kspace->datamask_modify); timer->stamp(Timer::KSPACE); } else force->kspace->compute_dummy(eflag,vflag); } if (force->newton) comm->reverse_comm(); modify->setup(vflag); + lmp->kokkos->auto_sync = 1; update->setupflag = 0; } /* ---------------------------------------------------------------------- run for N steps ------------------------------------------------------------------------- */ void VerletKokkos::run(int n) { bigint ntimestep; int nflag,sortflag; int n_post_integrate = modify->n_post_integrate; int n_pre_exchange = modify->n_pre_exchange; int n_pre_neighbor = modify->n_pre_neighbor; int n_pre_force = modify->n_pre_force; int n_post_force = modify->n_post_force; int n_end_of_step = modify->n_end_of_step; + lmp->kokkos->auto_sync = 0; + if (atomKK->sortfreq > 0) sortflag = 1; else sortflag = 0; f_merge_copy = DAT::t_f_array("VerletKokkos::f_merge_copy",atomKK->k_f.dimension_0()); static double time = 0.0; atomKK->sync(Device,ALL_MASK); Kokkos::Impl::Timer ktimer; timer->init_timeout(); for (int i = 0; i < n; i++) { if (timer->check_timeout(i)) { update->nsteps = i; break; } ntimestep = ++update->ntimestep; ev_set(ntimestep); // initial time integration ktimer.reset(); timer->stamp(); modify->initial_integrate(vflag); time += ktimer.seconds(); if (n_post_integrate) modify->post_integrate(); timer->stamp(Timer::MODIFY); // regular communication vs neighbor list rebuild nflag = neighbor->decide(); if (nflag == 0) { timer->stamp(); comm->forward_comm(); timer->stamp(Timer::COMM); } else { // added debug //atomKK->sync(Host,ALL_MASK); //atomKK->modified(Host,ALL_MASK); if (n_pre_exchange) { timer->stamp(); modify->pre_exchange(); timer->stamp(Timer::MODIFY); } // debug //atomKK->sync(Host,ALL_MASK); //atomKK->modified(Host,ALL_MASK); if (triclinic) domain->x2lamda(atomKK->nlocal); domain->pbc(); if (domain->box_change) { domain->reset_box(); comm->setup(); if (neighbor->style) neighbor->setup_bins(); } timer->stamp(); // added debug //atomKK->sync(Device,ALL_MASK); //atomKK->modified(Device,ALL_MASK); comm->exchange(); if (sortflag && ntimestep >= atomKK->nextsort) atomKK->sort(); comm->borders(); // added debug //atomKK->sync(Host,ALL_MASK); //atomKK->modified(Host,ALL_MASK); if (triclinic) domain->lamda2x(atomKK->nlocal+atomKK->nghost); timer->stamp(Timer::COMM); if (n_pre_neighbor) { modify->pre_neighbor(); timer->stamp(Timer::MODIFY); } neighbor->build(); timer->stamp(Timer::NEIGH); } // force computations // important for pair to come before bonded contributions // since some bonded potentials tally pairwise energy/virial // and Pair:ev_tally() needs to be called before any tallying force_clear(); timer->stamp(); if (n_pre_force) { modify->pre_force(vflag); timer->stamp(Timer::MODIFY); } bool execute_on_host = false; unsigned int datamask_read_device = 0; unsigned int datamask_modify_device = 0; unsigned int datamask_read_host = 0; if ( pair_compute_flag ) { if (force->pair->execution_space==Host) { execute_on_host = true; datamask_read_host |= force->pair->datamask_read; datamask_modify_device |= force->pair->datamask_modify; } else { datamask_read_device |= force->pair->datamask_read; datamask_modify_device |= force->pair->datamask_modify; } } if ( atomKK->molecular && force->bond ) { if (force->bond->execution_space==Host) { execute_on_host = true; datamask_read_host |= force->bond->datamask_read; datamask_modify_device |= force->bond->datamask_modify; } else { datamask_read_device |= force->bond->datamask_read; datamask_modify_device |= force->bond->datamask_modify; } } if ( atomKK->molecular && force->angle ) { if (force->angle->execution_space==Host) { execute_on_host = true; datamask_read_host |= force->angle->datamask_read; datamask_modify_device |= force->angle->datamask_modify; } else { datamask_read_device |= force->angle->datamask_read; datamask_modify_device |= force->angle->datamask_modify; } } if ( atomKK->molecular && force->dihedral ) { if (force->dihedral->execution_space==Host) { execute_on_host = true; datamask_read_host |= force->dihedral->datamask_read; datamask_modify_device |= force->dihedral->datamask_modify; } else { datamask_read_device |= force->dihedral->datamask_read; datamask_modify_device |= force->dihedral->datamask_modify; } } if ( atomKK->molecular && force->improper ) { if (force->improper->execution_space==Host) { execute_on_host = true; datamask_read_host |= force->improper->datamask_read; datamask_modify_device |= force->improper->datamask_modify; } else { datamask_read_device |= force->improper->datamask_read; datamask_modify_device |= force->improper->datamask_modify; } } if ( kspace_compute_flag ) { if (force->kspace->execution_space==Host) { execute_on_host = true; datamask_read_host |= force->kspace->datamask_read; datamask_modify_device |= force->kspace->datamask_modify; } else { datamask_read_device |= force->kspace->datamask_read; datamask_modify_device |= force->kspace->datamask_modify; } } if (pair_compute_flag) { atomKK->sync(force->pair->execution_space,force->pair->datamask_read); - atomKK->modified(force->pair->execution_space,force->pair->datamask_modify); atomKK->sync(force->pair->execution_space,~(~force->pair->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); - atomKK->modified(force->pair->execution_space,~(~force->pair->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); Kokkos::Impl::Timer ktimer; force->pair->compute(eflag,vflag); + atomKK->modified(force->pair->execution_space,force->pair->datamask_modify); + atomKK->modified(force->pair->execution_space,~(~force->pair->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); timer->stamp(Timer::PAIR); } if(execute_on_host) { if(pair_compute_flag && force->pair->datamask_modify!=(F_MASK | ENERGY_MASK | VIRIAL_MASK)) Kokkos::fence(); atomKK->sync_overlapping_device(Host,~(~datamask_read_host|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); if(pair_compute_flag && force->pair->execution_space!=Host) { Kokkos::deep_copy(LMPHostType(),atomKK->k_f.h_view,0.0); } } if (atomKK->molecular) { if (force->bond) { atomKK->sync(force->bond->execution_space,~(~force->bond->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); - atomKK->modified(force->bond->execution_space,~(~force->bond->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); force->bond->compute(eflag,vflag); + atomKK->modified(force->bond->execution_space,~(~force->bond->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); } if (force->angle) { atomKK->sync(force->angle->execution_space,~(~force->angle->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); - atomKK->modified(force->angle->execution_space,~(~force->angle->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); force->angle->compute(eflag,vflag); + atomKK->modified(force->angle->execution_space,~(~force->angle->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); } if (force->dihedral) { atomKK->sync(force->dihedral->execution_space,~(~force->dihedral->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); - atomKK->modified(force->dihedral->execution_space,~(~force->dihedral->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); force->dihedral->compute(eflag,vflag); + atomKK->modified(force->dihedral->execution_space,~(~force->dihedral->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); } if (force->improper) { atomKK->sync(force->improper->execution_space,~(~force->improper->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); - atomKK->modified(force->improper->execution_space,~(~force->improper->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); force->improper->compute(eflag,vflag); + atomKK->modified(force->improper->execution_space,~(~force->improper->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); } timer->stamp(Timer::BOND); } if (kspace_compute_flag) { atomKK->sync(force->kspace->execution_space,~(~force->kspace->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); - atomKK->modified(force->kspace->execution_space,~(~force->kspace->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); force->kspace->compute(eflag,vflag); + atomKK->modified(force->kspace->execution_space,~(~force->kspace->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK))); timer->stamp(Timer::KSPACE); } if(execute_on_host && !std::is_same::value) { if(f_merge_copy.dimension_0()k_f.dimension_0()) { f_merge_copy = DAT::t_f_array("VerletKokkos::f_merge_copy",atomKK->k_f.dimension_0()); } f = atomKK->k_f.d_view; Kokkos::deep_copy(LMPHostType(),f_merge_copy,atomKK->k_f.h_view); Kokkos::parallel_for(atomKK->k_f.dimension_0(), ForceAdder(atomKK->k_f.d_view,f_merge_copy)); + atomKK->k_f.modified_host() = 0; // special case atomKK->k_f.modify(); } // reverse communication of forces if (force->newton) comm->reverse_comm(); timer->stamp(Timer::COMM); // force modifications, final time integration, diagnostics if (n_post_force) modify->post_force(vflag); modify->final_integrate(); if (n_end_of_step) modify->end_of_step(); timer->stamp(Timer::MODIFY); // all output if (ntimestep == output->next) { atomKK->sync(Host,ALL_MASK); timer->stamp(); output->write(ntimestep); timer->stamp(Timer::OUTPUT); } } + + atomKK->sync(Host,ALL_MASK); + lmp->kokkos->auto_sync = 1; } /* ---------------------------------------------------------------------- clear force on own & ghost atoms clear other arrays as needed ------------------------------------------------------------------------- */ void VerletKokkos::force_clear() { int i; if (external_force_clear) return; // clear force on all particles // if either newton flag is set, also include ghosts // when using threads always clear all forces. if (neighbor->includegroup == 0) { int nall; if (force->newton) nall = atomKK->nlocal + atomKK->nghost; else nall = atomKK->nlocal; size_t nbytes = sizeof(double) * nall; if (nbytes) { if (atomKK->k_f.modified_host() > atomKK->k_f.modified_device()) { - memset_kokkos(atomKK->k_f.view()); - atomKK->modified(Host,F_MASK); + memset_kokkos(atomKK->k_f.view()); + atomKK->modified(Host,F_MASK); + atomKK->sync(Device,F_MASK); } else { memset_kokkos(atomKK->k_f.view()); atomKK->modified(Device,F_MASK); } if (torqueflag) memset(&(atomKK->torque[0][0]),0,3*nbytes); } // neighbor includegroup flag is set // clear force only on initial nfirst particles // if either newton flag is set, also include ghosts } else { int nall = atomKK->nfirst; if (atomKK->k_f.modified_host() > atomKK->k_f.modified_device()) { memset_kokkos(atomKK->k_f.view()); atomKK->modified(Host,F_MASK); } else { memset_kokkos(atomKK->k_f.view()); atomKK->modified(Device,F_MASK); } if (torqueflag) { double **torque = atomKK->torque; for (i = 0; i < nall; i++) { torque[i][0] = 0.0; torque[i][1] = 0.0; torque[i][2] = 0.0; } } if (force->newton) { nall = atomKK->nlocal + atomKK->nghost; if (torqueflag) { double **torque = atomKK->torque; for (i = atomKK->nlocal; i < nall; i++) { torque[i][0] = 0.0; torque[i][1] = 0.0; torque[i][2] = 0.0; } } } } } diff --git a/src/MANYBODY/pair_airebo.cpp b/src/MANYBODY/pair_airebo.cpp index 2bb1c1da2..51cf22166 100644 --- a/src/MANYBODY/pair_airebo.cpp +++ b/src/MANYBODY/pair_airebo.cpp @@ -1,4287 +1,4297 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Ase Henry (MIT) Bugfixes and optimizations: Marcel Fallet & Steve Stuart (Clemson), Axel Kohlmeyer (Temple U) AIREBO-M modification to optionally replace LJ with Morse potentials. Thomas C. O'Connor (JHU) 2014 ------------------------------------------------------------------------- */ #include #include #include #include #include #include "pair_airebo.h" #include "atom.h" #include "neighbor.h" #include "force.h" #include "comm.h" #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" #include "my_page.h" #include "math_const.h" #include "math_special.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; using namespace MathConst; using namespace MathSpecial; #define MAXLINE 1024 #define TOL 1.0e-9 #define PGDELTA 1 /* ---------------------------------------------------------------------- */ PairAIREBO::PairAIREBO(LAMMPS *lmp) : Pair(lmp) { single_enable = 0; one_coeff = 1; ghostneigh = 1; ljflag = torflag = 1; morseflag = 0; nextra = 3; pvector = new double[nextra]; maxlocal = 0; REBO_numneigh = NULL; REBO_firstneigh = NULL; ipage = NULL; pgsize = oneatom = 0; nC = nH = NULL; map = NULL; manybody_flag = 1; } /* ---------------------------------------------------------------------- check if allocated, since class can be destructed when incomplete ------------------------------------------------------------------------- */ PairAIREBO::~PairAIREBO() { memory->destroy(REBO_numneigh); memory->sfree(REBO_firstneigh); delete [] ipage; memory->destroy(nC); memory->destroy(nH); delete [] pvector; if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); memory->destroy(cutghost); memory->destroy(cutljsq); memory->destroy(lj1); memory->destroy(lj2); memory->destroy(lj3); memory->destroy(lj4); delete [] map; } } /* ---------------------------------------------------------------------- */ void PairAIREBO::compute(int eflag, int vflag) { if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = vflag_atom = 0; pvector[0] = pvector[1] = pvector[2] = 0.0; REBO_neigh(); FREBO(eflag,vflag); if (ljflag) FLJ(eflag,vflag); if (torflag) TORSION(eflag,vflag); if (vflag_fdotr) virial_fdotr_compute(); } /* ---------------------------------------------------------------------- allocate all arrays ------------------------------------------------------------------------- */ void PairAIREBO::allocate() { allocated = 1; int n = atom->ntypes; memory->create(setflag,n+1,n+1,"pair:setflag"); for (int i = 1; i <= n; i++) for (int j = i; j <= n; j++) setflag[i][j] = 0; memory->create(cutsq,n+1,n+1,"pair:cutsq"); memory->create(cutghost,n+1,n+1,"pair:cutghost"); // only sized by C,H = 2 types memory->create(cutljsq,2,2,"pair:cutljsq"); memory->create(lj1,2,2,"pair:lj1"); memory->create(lj2,2,2,"pair:lj2"); memory->create(lj3,2,2,"pair:lj3"); memory->create(lj4,2,2,"pair:lj4"); map = new int[n+1]; } /* ---------------------------------------------------------------------- global settings ------------------------------------------------------------------------- */ void PairAIREBO::settings(int narg, char **arg) { if (narg != 1 && narg != 3) error->all(FLERR,"Illegal pair_style command"); cutlj = force->numeric(FLERR,arg[0]); if (narg == 3) { ljflag = force->inumeric(FLERR,arg[1]); torflag = force->inumeric(FLERR,arg[2]); } + + // this one parameter for C-C interactions is different in AIREBO vs REBO + // see Favata, Micheletti, Ryu, Pugno, Comp Phys Comm (2016) + + PCCf_2_0 = -0.0276030; } /* ---------------------------------------------------------------------- set coeffs for one or more type pairs ------------------------------------------------------------------------- */ void PairAIREBO::coeff(int narg, char **arg) { if (!allocated) allocate(); if (narg != 3 + atom->ntypes) error->all(FLERR,"Incorrect args for pair coefficients"); // insure I,J args are * * if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) error->all(FLERR,"Incorrect args for pair coefficients"); // read args that map atom types to C and H // map[i] = which element (0,1) the Ith atom type is, -1 if NULL for (int i = 3; i < narg; i++) { if (strcmp(arg[i],"NULL") == 0) { map[i-2] = -1; continue; } else if (strcmp(arg[i],"C") == 0) { map[i-2] = 0; } else if (strcmp(arg[i],"H") == 0) { map[i-2] = 1; } else error->all(FLERR,"Incorrect args for pair coefficients"); } // read potential file and initialize fitting splines read_file(arg[2]); spline_init(); // clear setflag since coeff() called once with I,J = * * int n = atom->ntypes; for (int i = 1; i <= n; i++) for (int j = i; j <= n; j++) setflag[i][j] = 0; // set setflag i,j for type pairs where both are mapped to elements int count = 0; for (int i = 1; i <= n; i++) for (int j = i; j <= n; j++) if (map[i] >= 0 && map[j] >= 0) { setflag[i][j] = 1; count++; } if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- init specific to this pair style ------------------------------------------------------------------------- */ void PairAIREBO::init_style() { if (atom->tag_enable == 0) error->all(FLERR,"Pair style AIREBO requires atom IDs"); if (force->newton_pair == 0) error->all(FLERR,"Pair style AIREBO requires newton pair on"); // need a full neighbor list, including neighbors of ghosts int irequest = neighbor->request(this,instance_me); neighbor->requests[irequest]->half = 0; neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->ghost = 1; // local REBO neighbor list // create pages if first time or if neighbor pgsize/oneatom has changed int create = 0; if (ipage == NULL) create = 1; if (pgsize != neighbor->pgsize) create = 1; if (oneatom != neighbor->oneatom) create = 1; if (create) { delete [] ipage; pgsize = neighbor->pgsize; oneatom = neighbor->oneatom; int nmypage= comm->nthreads; ipage = new MyPage[nmypage]; for (int i = 0; i < nmypage; i++) ipage[i].init(oneatom,pgsize,PGDELTA); } } /* ---------------------------------------------------------------------- init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ double PairAIREBO::init_one(int i, int j) { if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); // convert to C,H types int ii = map[i]; int jj = map[j]; // use C-C values for these cutoffs since C atoms are biggest // cut3rebo = 3 REBO distances cut3rebo = 3.0 * rcmax[0][0]; // cutljrebosq = furthest distance from an owned atom a ghost atom can be // to need its REBO neighs computed // interaction = M-K-I-J-L-N with I = owned and J = ghost // this insures N is in the REBO neigh list of L // since I-J < rcLJmax and J-L < rmax double cutljrebo = rcLJmax[0][0] + rcmax[0][0]; cutljrebosq = cutljrebo * cutljrebo; // cutmax = furthest distance from an owned atom // at which another atom will feel force, i.e. the ghost cutoff // for REBO term in potential: // interaction = M-K-I-J-L-N with I = owned and J = ghost // I to N is max distance = 3 REBO distances // for LJ term in potential: // short interaction = M-K-I-J-L-N with I = owned, J = ghost, I-J < rcLJmax // rcLJmax + 2*rcmax, since I-J < rcLJmax and J-L,L-N = REBO distances // long interaction = I-J with I = owned and J = ghost // cutlj*sigma, since I-J < LJ cutoff // cutghost = REBO cutoff used in REBO_neigh() for neighbors of ghosts double cutmax = cut3rebo; if (ljflag) { cutmax = MAX(cutmax,rcLJmax[0][0] + 2.0*rcmax[0][0]); cutmax = MAX(cutmax,cutlj*sigma[0][0]); } cutghost[i][j] = rcmax[ii][jj]; cutljsq[ii][jj] = cutlj*sigma[ii][jj] * cutlj*sigma[ii][jj]; if (morseflag) { // using LJ precomputed parameter arrays to store values for Morse potential lj1[ii][jj] = epsilonM[ii][jj] * exp(alphaM[ii][jj]*reqM[ii][jj]); lj2[ii][jj] = exp(alphaM[ii][jj]*reqM[ii][jj]); lj3[ii][jj] = 2*epsilonM[ii][jj]*alphaM[ii][jj]*exp(alphaM[ii][jj]*reqM[ii][jj]); lj4[ii][jj] = alphaM[ii][jj]; } else { lj1[ii][jj] = 48.0 * epsilon[ii][jj] * pow(sigma[ii][jj],12.0); lj2[ii][jj] = 24.0 * epsilon[ii][jj] * pow(sigma[ii][jj],6.0); lj3[ii][jj] = 4.0 * epsilon[ii][jj] * pow(sigma[ii][jj],12.0); lj4[ii][jj] = 4.0 * epsilon[ii][jj] * pow(sigma[ii][jj],6.0); } cutghost[j][i] = cutghost[i][j]; cutljsq[jj][ii] = cutljsq[ii][jj]; lj1[jj][ii] = lj1[ii][jj]; lj2[jj][ii] = lj2[ii][jj]; lj3[jj][ii] = lj3[ii][jj]; lj4[jj][ii] = lj4[ii][jj]; return cutmax; } /* ---------------------------------------------------------------------- create REBO neighbor list from main neighbor list REBO neighbor list stores neighbors of ghost atoms ------------------------------------------------------------------------- */ void PairAIREBO::REBO_neigh() { int i,j,ii,jj,n,allnum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz,rsq,dS; int *ilist,*jlist,*numneigh,**firstneigh; int *neighptr; double **x = atom->x; int *type = atom->type; if (atom->nmax > maxlocal) { maxlocal = atom->nmax; memory->destroy(REBO_numneigh); memory->sfree(REBO_firstneigh); memory->destroy(nC); memory->destroy(nH); memory->create(REBO_numneigh,maxlocal,"AIREBO:numneigh"); REBO_firstneigh = (int **) memory->smalloc(maxlocal*sizeof(int *), "AIREBO:firstneigh"); memory->create(nC,maxlocal,"AIREBO:nC"); memory->create(nH,maxlocal,"AIREBO:nH"); } allnum = list->inum + list->gnum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; // store all REBO neighs of owned and ghost atoms // scan full neighbor list of I ipage->reset(); for (ii = 0; ii < allnum; ii++) { i = ilist[ii]; n = 0; neighptr = ipage->vget(); xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = map[type[i]]; nC[i] = nH[i] = 0.0; jlist = firstneigh[i]; jnum = numneigh[i]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; j &= NEIGHMASK; jtype = map[type[j]]; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; rsq = delx*delx + dely*dely + delz*delz; if (rsq < rcmaxsq[itype][jtype]) { neighptr[n++] = j; if (jtype == 0) nC[i] += Sp(sqrt(rsq),rcmin[itype][jtype],rcmax[itype][jtype],dS); else nH[i] += Sp(sqrt(rsq),rcmin[itype][jtype],rcmax[itype][jtype],dS); } } REBO_firstneigh[i] = neighptr; REBO_numneigh[i] = n; ipage->vgot(n); if (ipage->status()) error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); } } /* ---------------------------------------------------------------------- REBO forces and energy ------------------------------------------------------------------------- */ void PairAIREBO::FREBO(int eflag, int vflag) { int i,j,k,m,ii,inum,itype,jtype; tagint itag,jtag; double delx,dely,delz,evdwl,fpair,xtmp,ytmp,ztmp; double rsq,rij,wij; double Qij,Aij,alphaij,VR,pre,dVRdi,VA,term,bij,dVAdi,dVA; double dwij,del[3]; int *ilist,*REBO_neighs; evdwl = 0.0; double **x = atom->x; double **f = atom->f; int *type = atom->type; tagint *tag = atom->tag; int nlocal = atom->nlocal; int newton_pair = force->newton_pair; inum = list->inum; ilist = list->ilist; // two-body interactions from REBO neighbor list, skip half of them for (ii = 0; ii < inum; ii++) { i = ilist[ii]; itag = tag[i]; itype = map[type[i]]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; REBO_neighs = REBO_firstneigh[i]; for (k = 0; k < REBO_numneigh[i]; k++) { j = REBO_neighs[k]; jtag = tag[j]; if (itag > jtag) { if ((itag+jtag) % 2 == 0) continue; } else if (itag < jtag) { if ((itag+jtag) % 2 == 1) continue; } else { if (x[j][2] < ztmp) continue; if (x[j][2] == ztmp && x[j][1] < ytmp) continue; if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue; } jtype = map[type[j]]; delx = x[i][0] - x[j][0]; dely = x[i][1] - x[j][1]; delz = x[i][2] - x[j][2]; rsq = delx*delx + dely*dely + delz*delz; rij = sqrt(rsq); wij = Sp(rij,rcmin[itype][jtype],rcmax[itype][jtype],dwij); if (wij <= TOL) continue; Qij = Q[itype][jtype]; Aij = A[itype][jtype]; alphaij = alpha[itype][jtype]; VR = wij*(1.0+(Qij/rij)) * Aij*exp(-alphaij*rij); pre = wij*Aij * exp(-alphaij*rij); dVRdi = pre * ((-alphaij)-(Qij/rsq)-(Qij*alphaij/rij)); dVRdi += VR/wij * dwij; VA = dVA = 0.0; for (m = 0; m < 3; m++) { term = -wij * BIJc[itype][jtype][m] * exp(-Beta[itype][jtype][m]*rij); VA += term; dVA += -Beta[itype][jtype][m] * term; } dVA += VA/wij * dwij; del[0] = delx; del[1] = dely; del[2] = delz; bij = bondorder(i,j,del,rij,VA,f,vflag_atom); dVAdi = bij*dVA; fpair = -(dVRdi+dVAdi) / rij; f[i][0] += delx*fpair; f[i][1] += dely*fpair; f[i][2] += delz*fpair; f[j][0] -= delx*fpair; f[j][1] -= dely*fpair; f[j][2] -= delz*fpair; if (eflag) pvector[0] += evdwl = VR + bij*VA; if (evflag) ev_tally(i,j,nlocal,newton_pair, evdwl,0.0,fpair,delx,dely,delz); } } } /* ---------------------------------------------------------------------- compute LJ forces and energy find 3- and 4-step paths between atoms I,J via REBO neighbor lists ------------------------------------------------------------------------- */ void PairAIREBO::FLJ(int eflag, int vflag) { int i,j,k,m,ii,jj,kk,mm,inum,jnum,itype,jtype,ktype,mtype; int atomi,atomj,atomk,atomm; int testpath,npath,done; tagint itag,jtag; double evdwl,fpair,xtmp,ytmp,ztmp; double rsq,best,wik,wkm,cij,rij,dwij,dwik,dwkj,dwkm,dwmj; double delij[3],rijsq,delik[3],rik,deljk[3]; double rkj,wkj,dC,VLJ,dVLJ,VA,Str,dStr,Stb; double vdw,slw,dvdw,dslw,drij,swidth,tee,tee2; double rljmin,rljmax,sigcut,sigmin,sigwid; double delkm[3],rkm,deljm[3],rmj,wmj,r2inv,r6inv,scale,delscale[3]; int *ilist,*jlist,*numneigh,**firstneigh; int *REBO_neighs_i,*REBO_neighs_k; double delikS[3],deljkS[3],delkmS[3],deljmS[3],delimS[3]; double rikS,rkjS,rkmS,rmjS,wikS,dwikS; double wkjS,dwkjS,wkmS,dwkmS,wmjS,dwmjS; double fpair1,fpair2,fpair3; double fi[3],fj[3],fk[3],fm[3]; // I-J interaction from full neighbor list // skip 1/2 of interactions since only consider each pair once evdwl = 0.0; rljmin = 0.0; rljmax = 0.0; sigcut = 0.0; sigmin = 0.0; sigwid = 0.0; double **x = atom->x; double **f = atom->f; tagint *tag = atom->tag; int *type = atom->type; int nlocal = atom->nlocal; int newton_pair = force->newton_pair; inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; // loop over neighbors of my atoms for (ii = 0; ii < inum; ii++) { i = ilist[ii]; itag = tag[i]; itype = map[type[i]]; atomi = i; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; jlist = firstneigh[i]; jnum = numneigh[i]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; j &= NEIGHMASK; jtag = tag[j]; if (itag > jtag) { if ((itag+jtag) % 2 == 0) continue; } else if (itag < jtag) { if ((itag+jtag) % 2 == 1) continue; } else { if (x[j][2] < ztmp) continue; if (x[j][2] == ztmp && x[j][1] < ytmp) continue; if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue; } jtype = map[type[j]]; atomj = j; delij[0] = xtmp - x[j][0]; delij[1] = ytmp - x[j][1]; delij[2] = ztmp - x[j][2]; rijsq = delij[0]*delij[0] + delij[1]*delij[1] + delij[2]*delij[2]; // if outside of LJ cutoff, skip // if outside of 4-path cutoff, best = 0.0, no need to test paths // if outside of 2-path cutoff but inside 4-path cutoff, // best = 0.0, test 3-,4-paths // if inside 2-path cutoff, best = wij, only test 3-,4-paths if best < 1 npath = testpath = done = 0; best = 0.0; if (rijsq >= cutljsq[itype][jtype]) continue; rij = sqrt(rijsq); if (rij >= cut3rebo) { best = 0.0; testpath = 0; } else if (rij >= rcmax[itype][jtype]) { best = 0.0; testpath = 1; } else { best = Sp(rij,rcmin[itype][jtype],rcmax[itype][jtype],dwij); npath = 2; if (best < 1.0) testpath = 1; else testpath = 0; } if (testpath) { // test all 3-body paths = I-K-J // I-K interactions come from atom I's REBO neighbors // if wik > current best, compute wkj // if best = 1.0, done REBO_neighs_i = REBO_firstneigh[i]; for (kk = 0; kk < REBO_numneigh[i] && done==0; kk++) { k = REBO_neighs_i[kk]; if (k == j) continue; ktype = map[type[k]]; delik[0] = x[i][0] - x[k][0]; delik[1] = x[i][1] - x[k][1]; delik[2] = x[i][2] - x[k][2]; rsq = delik[0]*delik[0] + delik[1]*delik[1] + delik[2]*delik[2]; if (rsq < rcmaxsq[itype][ktype]) { rik = sqrt(rsq); wik = Sp(rik,rcmin[itype][ktype],rcmax[itype][ktype],dwik); } else { dwik = wik = 0.0; rikS = rik = 1.0; } if (wik > best) { deljk[0] = x[j][0] - x[k][0]; deljk[1] = x[j][1] - x[k][1]; deljk[2] = x[j][2] - x[k][2]; rsq = deljk[0]*deljk[0] + deljk[1]*deljk[1] + deljk[2]*deljk[2]; if (rsq < rcmaxsq[ktype][jtype]) { rkj = sqrt(rsq); wkj = Sp(rkj,rcmin[ktype][jtype],rcmax[ktype][jtype],dwkj); if (wik*wkj > best) { best = wik*wkj; npath = 3; atomk = k; delikS[0] = delik[0]; delikS[1] = delik[1]; delikS[2] = delik[2]; rikS = rik; wikS = wik; dwikS = dwik; deljkS[0] = deljk[0]; deljkS[1] = deljk[1]; deljkS[2] = deljk[2]; rkjS = rkj; wkjS = wkj; dwkjS = dwkj; if (best == 1.0) { done = 1; break; } } } // test all 4-body paths = I-K-M-J // K-M interactions come from atom K's REBO neighbors // if wik*wkm > current best, compute wmj // if best = 1.0, done REBO_neighs_k = REBO_firstneigh[k]; for (mm = 0; mm < REBO_numneigh[k] && done==0; mm++) { m = REBO_neighs_k[mm]; if (m == i || m == j) continue; mtype = map[type[m]]; delkm[0] = x[k][0] - x[m][0]; delkm[1] = x[k][1] - x[m][1]; delkm[2] = x[k][2] - x[m][2]; rsq = delkm[0]*delkm[0] + delkm[1]*delkm[1] + delkm[2]*delkm[2]; if (rsq < rcmaxsq[ktype][mtype]) { rkm = sqrt(rsq); wkm = Sp(rkm,rcmin[ktype][mtype],rcmax[ktype][mtype],dwkm); } else { dwkm = wkm = 0.0; rkmS = rkm = 1.0; } if (wik*wkm > best) { deljm[0] = x[j][0] - x[m][0]; deljm[1] = x[j][1] - x[m][1]; deljm[2] = x[j][2] - x[m][2]; rsq = deljm[0]*deljm[0] + deljm[1]*deljm[1] + deljm[2]*deljm[2]; if (rsq < rcmaxsq[mtype][jtype]) { rmj = sqrt(rsq); wmj = Sp(rmj,rcmin[mtype][jtype],rcmax[mtype][jtype],dwmj); if (wik*wkm*wmj > best) { best = wik*wkm*wmj; npath = 4; atomk = k; delikS[0] = delik[0]; delikS[1] = delik[1]; delikS[2] = delik[2]; rikS = rik; wikS = wik; dwikS = dwik; atomm = m; delkmS[0] = delkm[0]; delkmS[1] = delkm[1]; delkmS[2] = delkm[2]; rkmS = rkm; wkmS = wkm; dwkmS = dwkm; deljmS[0] = deljm[0]; deljmS[1] = deljm[1]; deljmS[2] = deljm[2]; rmjS = rmj; wmjS = wmj; dwmjS = dwmj; if (best == 1.0) { done = 1; break; } } } } } } } } cij = 1.0 - best; if (cij == 0.0) continue; // compute LJ forces and energy sigwid = 0.84; sigcut = 3.0; sigmin = sigcut - sigwid; rljmin = sigma[itype][jtype]; rljmax = sigcut * rljmin; rljmin = sigmin * rljmin; if (rij > rljmax) { slw = 0.0; dslw = 0.0; } else if (rij > rljmin) { drij = rij - rljmin; swidth = rljmax - rljmin; tee = drij / swidth; tee2 = tee*tee; slw = 1.0 - tee2 * (3.0 - 2.0 * tee); dslw = 6.0 * tee * (1.0 - tee) / rij / swidth; } else { slw = 1.0; dslw = 0.0; } if (morseflag) { const double exr = exp(-rij*lj4[itype][jtype]); vdw = lj1[itype][jtype]*exr*(lj2[itype][jtype]*exr - 2); dvdw = lj3[itype][jtype]*exr*(1-lj2[itype][jtype]*exr); } else { r2inv = 1.0/rijsq; r6inv = r2inv*r2inv*r2inv; vdw = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); dvdw = -r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]) / rij; } // VLJ now becomes vdw * slw, derivaties, etc. VLJ = vdw * slw; dVLJ = dvdw * slw + vdw * dslw; Str = Sp2(rij,rcLJmin[itype][jtype],rcLJmax[itype][jtype],dStr); VA = Str*cij*VLJ; if (Str > 0.0) { scale = rcmin[itype][jtype] / rij; delscale[0] = scale * delij[0]; delscale[1] = scale * delij[1]; delscale[2] = scale * delij[2]; Stb = bondorderLJ(i,j,delscale,rcmin[itype][jtype],VA, delij,rij,f,vflag_atom); } else Stb = 0.0; fpair = -(dStr * (Stb*cij*VLJ - cij*VLJ) + dVLJ * (Str*Stb*cij + cij - Str*cij)) / rij; f[i][0] += delij[0]*fpair; f[i][1] += delij[1]*fpair; f[i][2] += delij[2]*fpair; f[j][0] -= delij[0]*fpair; f[j][1] -= delij[1]*fpair; f[j][2] -= delij[2]*fpair; if (eflag) pvector[1] += evdwl = VA*Stb + (1.0-Str)*cij*VLJ; if (evflag) ev_tally(i,j,nlocal,newton_pair, evdwl,0.0,fpair,delij[0],delij[1],delij[2]); if (cij < 1.0) { dC = Str*Stb*VLJ + (1.0-Str)*VLJ; if (npath == 2) { fpair = dC*dwij / rij; f[atomi][0] += delij[0]*fpair; f[atomi][1] += delij[1]*fpair; f[atomi][2] += delij[2]*fpair; f[atomj][0] -= delij[0]*fpair; f[atomj][1] -= delij[1]*fpair; f[atomj][2] -= delij[2]*fpair; if (vflag_atom) v_tally2(atomi,atomj,fpair,delij); } else if (npath == 3) { fpair1 = dC*dwikS*wkjS / rikS; fi[0] = delikS[0]*fpair1; fi[1] = delikS[1]*fpair1; fi[2] = delikS[2]*fpair1; fpair2 = dC*wikS*dwkjS / rkjS; fj[0] = deljkS[0]*fpair2; fj[1] = deljkS[1]*fpair2; fj[2] = deljkS[2]*fpair2; f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2]; f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2]; f[atomk][0] -= fi[0] + fj[0]; f[atomk][1] -= fi[1] + fj[1]; f[atomk][2] -= fi[2] + fj[2]; if (vflag_atom) v_tally3(atomi,atomj,atomk,fi,fj,delikS,deljkS); } else if (npath == 4) { fpair1 = dC*dwikS*wkmS*wmjS / rikS; fi[0] = delikS[0]*fpair1; fi[1] = delikS[1]*fpair1; fi[2] = delikS[2]*fpair1; fpair2 = dC*wikS*dwkmS*wmjS / rkmS; fk[0] = delkmS[0]*fpair2 - fi[0]; fk[1] = delkmS[1]*fpair2 - fi[1]; fk[2] = delkmS[2]*fpair2 - fi[2]; fpair3 = dC*wikS*wkmS*dwmjS / rmjS; fj[0] = deljmS[0]*fpair3; fj[1] = deljmS[1]*fpair3; fj[2] = deljmS[2]*fpair3; fm[0] = -delkmS[0]*fpair2 - fj[0]; fm[1] = -delkmS[1]*fpair2 - fj[1]; fm[2] = -delkmS[2]*fpair2 - fj[2]; f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2]; f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2]; f[atomk][0] += fk[0]; f[atomk][1] += fk[1]; f[atomk][2] += fk[2]; f[atomm][0] += fm[0]; f[atomm][1] += fm[1]; f[atomm][2] += fm[2]; if (vflag_atom) { delimS[0] = delikS[0] + delkmS[0]; delimS[1] = delikS[1] + delkmS[1]; delimS[2] = delikS[2] + delkmS[2]; v_tally4(atomi,atomj,atomk,atomm,fi,fj,fk,delimS,deljmS,delkmS); } } } } } } /* ---------------------------------------------------------------------- torsional forces and energy ------------------------------------------------------------------------- */ void PairAIREBO::TORSION(int eflag, int vflag) { int i,j,k,l,ii,inum; tagint itag,jtag; double evdwl,fpair,xtmp,ytmp,ztmp; double cos321; double w21,dw21,cos234,w34,dw34; double cross321[3],cross321mag,cross234[3],cross234mag; double w23,dw23,cw2,ekijl,Ec; double cw,cwnum,cwnom; double rij,rij2,rik,rjl,tspjik,dtsjik,tspijl,dtsijl,costmp,fcpc; double sin321,sin234,rjk2,rik2,ril2,rjl2; double rjk,ril; double Vtors; double dndij[3],tmpvec[3],dndik[3],dndjl[3]; double dcidij,dcidik,dcidjk,dcjdji,dcjdjl,dcjdil; double dsidij,dsidik,dsidjk,dsjdji,dsjdjl,dsjdil; double dxidij,dxidik,dxidjk,dxjdji,dxjdjl,dxjdil; double ddndij,ddndik,ddndjk,ddndjl,ddndil,dcwddn,dcwdn,dvpdcw,Ftmp[3]; double del32[3],rsq,r32,del23[3],del21[3],r21; double deljk[3],del34[3],delil[3],delkl[3],r23,r34; double fi[3],fj[3],fk[3],fl[3]; int itype,jtype,ktype,ltype,kk,ll,jj; int *ilist,*REBO_neighs_i,*REBO_neighs_j; double **x = atom->x; double **f = atom->f; int *type = atom->type; tagint *tag = atom->tag; inum = list->inum; ilist = list->ilist; for (ii = 0; ii < inum; ii++) { i = ilist[ii]; itag = tag[i]; itype = map[type[i]]; if (itype != 0) continue; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; REBO_neighs_i = REBO_firstneigh[i]; for (jj = 0; jj < REBO_numneigh[i]; jj++) { j = REBO_neighs_i[jj]; jtag = tag[j]; if (itag > jtag) { if ((itag+jtag) % 2 == 0) continue; } else if (itag < jtag) { if ((itag+jtag) % 2 == 1) continue; } else { if (x[j][2] < ztmp) continue; if (x[j][2] == ztmp && x[j][1] < ytmp) continue; if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue; } jtype = map[type[j]]; if (jtype != 0) continue; del32[0] = x[j][0]-x[i][0]; del32[1] = x[j][1]-x[i][1]; del32[2] = x[j][2]-x[i][2]; rsq = del32[0]*del32[0] + del32[1]*del32[1] + del32[2]*del32[2]; r32 = sqrt(rsq); del23[0] = -del32[0]; del23[1] = -del32[1]; del23[2] = -del32[2]; r23 = r32; w23 = Sp(r23,rcmin[itype][jtype],rcmax[itype][jtype],dw23); for (kk = 0; kk < REBO_numneigh[i]; kk++) { k = REBO_neighs_i[kk]; ktype = map[type[k]]; if (k == j) continue; del21[0] = x[i][0]-x[k][0]; del21[1] = x[i][1]-x[k][1]; del21[2] = x[i][2]-x[k][2]; rsq = del21[0]*del21[0] + del21[1]*del21[1] + del21[2]*del21[2]; r21 = sqrt(rsq); cos321 = - ((del21[0]*del32[0]) + (del21[1]*del32[1]) + (del21[2]*del32[2])) / (r21*r32); cos321 = MIN(cos321,1.0); cos321 = MAX(cos321,-1.0); sin321 = sqrt(1.0 - cos321*cos321); if (sin321 < TOL) continue; deljk[0] = del21[0]-del23[0]; deljk[1] = del21[1]-del23[1]; deljk[2] = del21[2]-del23[2]; rjk2 = deljk[0]*deljk[0] + deljk[1]*deljk[1] + deljk[2]*deljk[2]; rjk=sqrt(rjk2); rik2 = r21*r21; w21 = Sp(r21,rcmin[itype][ktype],rcmax[itype][ktype],dw21); rij = r32; rik = r21; rij2 = r32*r32; rik2 = r21*r21; costmp = 0.5*(rij2+rik2-rjk2)/rij/rik; tspjik = Sp2(costmp,thmin,thmax,dtsjik); dtsjik = -dtsjik; REBO_neighs_j = REBO_firstneigh[j]; for (ll = 0; ll < REBO_numneigh[j]; ll++) { l = REBO_neighs_j[ll]; ltype = map[type[l]]; if (l == i || l == k) continue; del34[0] = x[j][0]-x[l][0]; del34[1] = x[j][1]-x[l][1]; del34[2] = x[j][2]-x[l][2]; rsq = del34[0]*del34[0] + del34[1]*del34[1] + del34[2]*del34[2]; r34 = sqrt(rsq); cos234 = (del32[0]*del34[0] + del32[1]*del34[1] + del32[2]*del34[2]) / (r32*r34); cos234 = MIN(cos234,1.0); cos234 = MAX(cos234,-1.0); sin234 = sqrt(1.0 - cos234*cos234); if (sin234 < TOL) continue; w34 = Sp(r34,rcmin[jtype][ltype],rcmax[jtype][ltype],dw34); delil[0] = del23[0] + del34[0]; delil[1] = del23[1] + del34[1]; delil[2] = del23[2] + del34[2]; ril2 = delil[0]*delil[0] + delil[1]*delil[1] + delil[2]*delil[2]; ril=sqrt(ril2); rjl2 = r34*r34; rjl = r34; rjl2 = r34*r34; costmp = 0.5*(rij2+rjl2-ril2)/rij/rjl; tspijl = Sp2(costmp,thmin,thmax,dtsijl); dtsijl = -dtsijl; //need minus sign cross321[0] = (del32[1]*del21[2])-(del32[2]*del21[1]); cross321[1] = (del32[2]*del21[0])-(del32[0]*del21[2]); cross321[2] = (del32[0]*del21[1])-(del32[1]*del21[0]); cross321mag = sqrt(cross321[0]*cross321[0]+ cross321[1]*cross321[1]+ cross321[2]*cross321[2]); cross234[0] = (del23[1]*del34[2])-(del23[2]*del34[1]); cross234[1] = (del23[2]*del34[0])-(del23[0]*del34[2]); cross234[2] = (del23[0]*del34[1])-(del23[1]*del34[0]); cross234mag = sqrt(cross234[0]*cross234[0]+ cross234[1]*cross234[1]+ cross234[2]*cross234[2]); cwnum = (cross321[0]*cross234[0]) + (cross321[1]*cross234[1])+(cross321[2]*cross234[2]); cwnom = r21*r34*r32*r32*sin321*sin234; cw = cwnum/cwnom; cw2 = (.5*(1.0-cw)); ekijl = epsilonT[ktype][ltype]; Ec = 256.0*ekijl/405.0; Vtors = (Ec*(powint(cw2,5)))-(ekijl/10.0); if (eflag) pvector[2] += evdwl = Vtors*w21*w23*w34*(1.0-tspjik)*(1.0-tspijl); dndij[0] = (cross234[1]*del21[2])-(cross234[2]*del21[1]); dndij[1] = (cross234[2]*del21[0])-(cross234[0]*del21[2]); dndij[2] = (cross234[0]*del21[1])-(cross234[1]*del21[0]); tmpvec[0] = (del34[1]*cross321[2])-(del34[2]*cross321[1]); tmpvec[1] = (del34[2]*cross321[0])-(del34[0]*cross321[2]); tmpvec[2] = (del34[0]*cross321[1])-(del34[1]*cross321[0]); dndij[0] = dndij[0]+tmpvec[0]; dndij[1] = dndij[1]+tmpvec[1]; dndij[2] = dndij[2]+tmpvec[2]; dndik[0] = (del23[1]*cross234[2])-(del23[2]*cross234[1]); dndik[1] = (del23[2]*cross234[0])-(del23[0]*cross234[2]); dndik[2] = (del23[0]*cross234[1])-(del23[1]*cross234[0]); dndjl[0] = (cross321[1]*del23[2])-(cross321[2]*del23[1]); dndjl[1] = (cross321[2]*del23[0])-(cross321[0]*del23[2]); dndjl[2] = (cross321[0]*del23[1])-(cross321[1]*del23[0]); dcidij = ((r23*r23)-(r21*r21)+(rjk*rjk))/(2.0*r23*r23*r21); dcidik = ((r21*r21)-(r23*r23)+(rjk*rjk))/(2.0*r23*r21*r21); dcidjk = (-rjk)/(r23*r21); dcjdji = ((r23*r23)-(r34*r34)+(ril*ril))/(2.0*r23*r23*r34); dcjdjl = ((r34*r34)-(r23*r23)+(ril*ril))/(2.0*r23*r34*r34); dcjdil = (-ril)/(r23*r34); dsidij = (-cos321/sin321)*dcidij; dsidik = (-cos321/sin321)*dcidik; dsidjk = (-cos321/sin321)*dcidjk; dsjdji = (-cos234/sin234)*dcjdji; dsjdjl = (-cos234/sin234)*dcjdjl; dsjdil = (-cos234/sin234)*dcjdil; dxidij = (r21*sin321)+(r23*r21*dsidij); dxidik = (r23*sin321)+(r23*r21*dsidik); dxidjk = (r23*r21*dsidjk); dxjdji = (r34*sin234)+(r23*r34*dsjdji); dxjdjl = (r23*sin234)+(r23*r34*dsjdjl); dxjdil = (r23*r34*dsjdil); ddndij = (dxidij*cross234mag)+(cross321mag*dxjdji); ddndik = dxidik*cross234mag; ddndjk = dxidjk*cross234mag; ddndjl = cross321mag*dxjdjl; ddndil = cross321mag*dxjdil; dcwddn = -cwnum/(cwnom*cwnom); dcwdn = 1.0/cwnom; dvpdcw = (-1.0)*Ec*(-.5)*5.0*powint(cw2,4) * w23*w21*w34*(1.0-tspjik)*(1.0-tspijl); Ftmp[0] = dvpdcw*((dcwdn*dndij[0])+(dcwddn*ddndij*del23[0]/r23)); Ftmp[1] = dvpdcw*((dcwdn*dndij[1])+(dcwddn*ddndij*del23[1]/r23)); Ftmp[2] = dvpdcw*((dcwdn*dndij[2])+(dcwddn*ddndij*del23[2]/r23)); fi[0] = Ftmp[0]; fi[1] = Ftmp[1]; fi[2] = Ftmp[2]; fj[0] = -Ftmp[0]; fj[1] = -Ftmp[1]; fj[2] = -Ftmp[2]; Ftmp[0] = dvpdcw*((dcwdn*dndik[0])+(dcwddn*ddndik*del21[0]/r21)); Ftmp[1] = dvpdcw*((dcwdn*dndik[1])+(dcwddn*ddndik*del21[1]/r21)); Ftmp[2] = dvpdcw*((dcwdn*dndik[2])+(dcwddn*ddndik*del21[2]/r21)); fi[0] += Ftmp[0]; fi[1] += Ftmp[1]; fi[2] += Ftmp[2]; fk[0] = -Ftmp[0]; fk[1] = -Ftmp[1]; fk[2] = -Ftmp[2]; Ftmp[0] = (dvpdcw*dcwddn*ddndjk*deljk[0])/rjk; Ftmp[1] = (dvpdcw*dcwddn*ddndjk*deljk[1])/rjk; Ftmp[2] = (dvpdcw*dcwddn*ddndjk*deljk[2])/rjk; fj[0] += Ftmp[0]; fj[1] += Ftmp[1]; fj[2] += Ftmp[2]; fk[0] -= Ftmp[0]; fk[1] -= Ftmp[1]; fk[2] -= Ftmp[2]; Ftmp[0] = dvpdcw*((dcwdn*dndjl[0])+(dcwddn*ddndjl*del34[0]/r34)); Ftmp[1] = dvpdcw*((dcwdn*dndjl[1])+(dcwddn*ddndjl*del34[1]/r34)); Ftmp[2] = dvpdcw*((dcwdn*dndjl[2])+(dcwddn*ddndjl*del34[2]/r34)); fj[0] += Ftmp[0]; fj[1] += Ftmp[1]; fj[2] += Ftmp[2]; fl[0] = -Ftmp[0]; fl[1] = -Ftmp[1]; fl[2] = -Ftmp[2]; Ftmp[0] = (dvpdcw*dcwddn*ddndil*delil[0])/ril; Ftmp[1] = (dvpdcw*dcwddn*ddndil*delil[1])/ril; Ftmp[2] = (dvpdcw*dcwddn*ddndil*delil[2])/ril; fi[0] += Ftmp[0]; fi[1] += Ftmp[1]; fi[2] += Ftmp[2]; fl[0] -= Ftmp[0]; fl[1] -= Ftmp[1]; fl[2] -= Ftmp[2]; // coordination forces fpair = Vtors*dw21*w23*w34*(1.0-tspjik)*(1.0-tspijl) / r21; fi[0] -= del21[0]*fpair; fi[1] -= del21[1]*fpair; fi[2] -= del21[2]*fpair; fk[0] += del21[0]*fpair; fk[1] += del21[1]*fpair; fk[2] += del21[2]*fpair; fpair = Vtors*w21*dw23*w34*(1.0-tspjik)*(1.0-tspijl) / r23; fi[0] -= del23[0]*fpair; fi[1] -= del23[1]*fpair; fi[2] -= del23[2]*fpair; fj[0] += del23[0]*fpair; fj[1] += del23[1]*fpair; fj[2] += del23[2]*fpair; fpair = Vtors*w21*w23*dw34*(1.0-tspjik)*(1.0-tspijl) / r34; fj[0] -= del34[0]*fpair; fj[1] -= del34[1]*fpair; fj[2] -= del34[2]*fpair; fl[0] += del34[0]*fpair; fl[1] += del34[1]*fpair; fl[2] += del34[2]*fpair; // additional cut off function forces fcpc = -Vtors*w21*w23*w34*dtsjik*(1.0-tspijl); fpair = fcpc*dcidij/rij; fi[0] += fpair*del23[0]; fi[1] += fpair*del23[1]; fi[2] += fpair*del23[2]; fj[0] -= fpair*del23[0]; fj[1] -= fpair*del23[1]; fj[2] -= fpair*del23[2]; fpair = fcpc*dcidik/rik; fi[0] += fpair*del21[0]; fi[1] += fpair*del21[1]; fi[2] += fpair*del21[2]; fk[0] -= fpair*del21[0]; fk[1] -= fpair*del21[1]; fk[2] -= fpair*del21[2]; fpair = fcpc*dcidjk/rjk; fj[0] += fpair*deljk[0]; fj[1] += fpair*deljk[1]; fj[2] += fpair*deljk[2]; fk[0] -= fpair*deljk[0]; fk[1] -= fpair*deljk[1]; fk[2] -= fpair*deljk[2]; fcpc = -Vtors*w21*w23*w34*(1.0-tspjik)*dtsijl; fpair = fcpc*dcjdji/rij; fi[0] += fpair*del23[0]; fi[1] += fpair*del23[1]; fi[2] += fpair*del23[2]; fj[0] -= fpair*del23[0]; fj[1] -= fpair*del23[1]; fj[2] -= fpair*del23[2]; fpair = fcpc*dcjdjl/rjl; fj[0] += fpair*del34[0]; fj[1] += fpair*del34[1]; fj[2] += fpair*del34[2]; fl[0] -= fpair*del34[0]; fl[1] -= fpair*del34[1]; fl[2] -= fpair*del34[2]; fpair = fcpc*dcjdil/ril; fi[0] += fpair*delil[0]; fi[1] += fpair*delil[1]; fi[2] += fpair*delil[2]; fl[0] -= fpair*delil[0]; fl[1] -= fpair*delil[1]; fl[2] -= fpair*delil[2]; // sum per-atom forces into atom force array f[i][0] += fi[0]; f[i][1] += fi[1]; f[i][2] += fi[2]; f[j][0] += fj[0]; f[j][1] += fj[1]; f[j][2] += fj[2]; f[k][0] += fk[0]; f[k][1] += fk[1]; f[k][2] += fk[2]; f[l][0] += fl[0]; f[l][1] += fl[1]; f[l][2] += fl[2]; if (evflag) { delkl[0] = delil[0] - del21[0]; delkl[1] = delil[1] - del21[1]; delkl[2] = delil[2] - del21[2]; ev_tally4(i,j,k,l,evdwl,fi,fj,fk,delil,del34,delkl); } } } } } } /* ---------------------------------------------------------------------- Bij function ------------------------------------------------------------------------- */ double PairAIREBO::bondorder(int i, int j, double rij[3], double rijmag, double VA, double **f, int vflag_atom) { int atomi,atomj,k,n,l,atomk,atoml,atomn,atom1,atom2,atom3,atom4; int itype,jtype,ktype,ltype,ntype; double rik[3],rjl[3],rkn[3],rji[3],rki[3],rlj[3],rknmag,dNki,dwjl,bij; double NijC,NijH,NjiC,NjiH,wik,dwik,dwkn,wjl; double rikmag,rjlmag,cosjik,cosijl,g,tmp2,tmp3; double Etmp,pij,tmp,wij,dwij,NconjtmpI,NconjtmpJ,Nki,Nlj,dS; double lamdajik,lamdaijl,dgdc,dgdN,pji,Nijconj,piRC; double dcosjikdri[3],dcosijldri[3],dcosjikdrk[3]; double dN2[2],dN3[3]; double dcosjikdrj[3],dcosijldrj[3],dcosijldrl[3]; double Tij; double r32[3],r32mag,cos321,r43[3],r13[3]; double dNlj; double om1234,rln[3]; double rlnmag,dwln,r23[3],r23mag,r21[3],r21mag; double w21,dw21,r34[3],r34mag,cos234,w34,dw34; double cross321[3],cross234[3],prefactor,SpN; double fcijpc,fcikpc,fcjlpc,fcjkpc,fcilpc; double dt2dik[3],dt2djl[3],dt2dij[3],aa,aaa1,aaa2,at2,cw,cwnum,cwnom; double sin321,sin234,rr,rijrik,rijrjl,rjk2,rik2,ril2,rjl2; double dctik,dctjk,dctjl,dctij,dctji,dctil,rik2i,rjl2i,sink2i,sinl2i; double rjk[3],ril[3],dt1dik,dt1djk,dt1djl,dt1dil,dt1dij; double F23[3],F12[3],F34[3],F31[3],F24[3],fi[3],fj[3],fk[3],fl[3]; double f1[3],f2[3],f3[3],f4[4]; double dcut321,PijS,PjiS; double rij2,tspjik,dtsjik,tspijl,dtsijl,costmp; int *REBO_neighs,*REBO_neighs_i,*REBO_neighs_j,*REBO_neighs_k,*REBO_neighs_l; double **x = atom->x; int *type = atom->type; atomi = i; atomj = j; itype = map[type[i]]; jtype = map[type[j]]; wij = Sp(rijmag,rcmin[itype][jtype],rcmax[itype][jtype],dwij); NijC = nC[i]-(wij*kronecker(jtype,0)); NijH = nH[i]-(wij*kronecker(jtype,1)); NjiC = nC[j]-(wij*kronecker(itype,0)); NjiH = nH[j]-(wij*kronecker(itype,1)); bij = 0.0; tmp = 0.0; tmp2 = 0.0; tmp3 = 0.0; dgdc = 0.0; dgdN = 0.0; NconjtmpI = 0.0; NconjtmpJ = 0.0; Etmp = 0.0; REBO_neighs = REBO_firstneigh[i]; for (k = 0; k < REBO_numneigh[i]; k++) { atomk = REBO_neighs[k]; if (atomk != atomj) { ktype = map[type[atomk]]; rik[0] = x[atomi][0]-x[atomk][0]; rik[1] = x[atomi][1]-x[atomk][1]; rik[2] = x[atomi][2]-x[atomk][2]; rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2])); lamdajik = 4.0*kronecker(itype,1) * ((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag)); wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dS); Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] - (wik*kronecker(itype,1)); cosjik = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) / (rijmag*rikmag); cosjik = MIN(cosjik,1.0); cosjik = MAX(cosjik,-1.0); // evaluate splines g and derivatives dg g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN); Etmp = Etmp+(wik*g*exp(lamdajik)); tmp3 = tmp3+(wik*dgdN*exp(lamdajik)); NconjtmpI = NconjtmpI+(kronecker(ktype,0)*wik*Sp(Nki,Nmin,Nmax,dS)); } } PijS = 0.0; dN2[0] = 0.0; dN2[1] = 0.0; PijS = PijSpline(NijC,NijH,itype,jtype,dN2); pij = pow(1.0+Etmp+PijS,-0.5); tmp = -0.5*cube(pij); // pij forces REBO_neighs = REBO_firstneigh[i]; for (k = 0; k < REBO_numneigh[i]; k++) { atomk = REBO_neighs[k]; if (atomk != atomj) { ktype = map[type[atomk]]; rik[0] = x[atomi][0]-x[atomk][0]; rik[1] = x[atomi][1]-x[atomk][1]; rik[2] = x[atomi][2]-x[atomk][2]; rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2])); lamdajik = 4.0*kronecker(itype,1) * ((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag)); wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik); cosjik = (rij[0]*rik[0] + rij[1]*rik[1] + rij[2]*rik[2]) / (rijmag*rikmag); cosjik = MIN(cosjik,1.0); cosjik = MAX(cosjik,-1.0); dcosjikdri[0] = ((rij[0]+rik[0])/(rijmag*rikmag)) - (cosjik*((rij[0]/(rijmag*rijmag))+(rik[0]/(rikmag*rikmag)))); dcosjikdri[1] = ((rij[1]+rik[1])/(rijmag*rikmag)) - (cosjik*((rij[1]/(rijmag*rijmag))+(rik[1]/(rikmag*rikmag)))); dcosjikdri[2] = ((rij[2]+rik[2])/(rijmag*rikmag)) - (cosjik*((rij[2]/(rijmag*rijmag))+(rik[2]/(rikmag*rikmag)))); dcosjikdrk[0] = (-rij[0]/(rijmag*rikmag)) + (cosjik*(rik[0]/(rikmag*rikmag))); dcosjikdrk[1] = (-rij[1]/(rijmag*rikmag)) + (cosjik*(rik[1]/(rikmag*rikmag))); dcosjikdrk[2] = (-rij[2]/(rijmag*rikmag)) + (cosjik*(rik[2]/(rikmag*rikmag))); dcosjikdrj[0] = (-rik[0]/(rijmag*rikmag)) + (cosjik*(rij[0]/(rijmag*rijmag))); dcosjikdrj[1] = (-rik[1]/(rijmag*rikmag)) + (cosjik*(rij[1]/(rijmag*rijmag))); dcosjikdrj[2] = (-rik[2]/(rijmag*rikmag)) + (cosjik*(rij[2]/(rijmag*rijmag))); g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN); tmp2 = VA*.5*(tmp*wik*dgdc*exp(lamdajik)); fj[0] = -tmp2*dcosjikdrj[0]; fj[1] = -tmp2*dcosjikdrj[1]; fj[2] = -tmp2*dcosjikdrj[2]; fi[0] = -tmp2*dcosjikdri[0]; fi[1] = -tmp2*dcosjikdri[1]; fi[2] = -tmp2*dcosjikdri[2]; fk[0] = -tmp2*dcosjikdrk[0]; fk[1] = -tmp2*dcosjikdrk[1]; fk[2] = -tmp2*dcosjikdrk[2]; tmp2 = VA*.5*(tmp*wik*g*exp(lamdajik)*4.0*kronecker(itype,1)); fj[0] -= tmp2*(-rij[0]/rijmag); fj[1] -= tmp2*(-rij[1]/rijmag); fj[2] -= tmp2*(-rij[2]/rijmag); fi[0] -= tmp2*((-rik[0]/rikmag)+(rij[0]/rijmag)); fi[1] -= tmp2*((-rik[1]/rikmag)+(rij[1]/rijmag)); fi[2] -= tmp2*((-rik[2]/rikmag)+(rij[2]/rijmag)); fk[0] -= tmp2*(rik[0]/rikmag); fk[1] -= tmp2*(rik[1]/rikmag); fk[2] -= tmp2*(rik[2]/rikmag); // coordination forces // dwik forces tmp2 = VA*.5*(tmp*dwik*g*exp(lamdajik))/rikmag; fi[0] -= tmp2*rik[0]; fi[1] -= tmp2*rik[1]; fi[2] -= tmp2*rik[2]; fk[0] += tmp2*rik[0]; fk[1] += tmp2*rik[1]; fk[2] += tmp2*rik[2]; // PIJ forces tmp2 = VA*.5*(tmp*dN2[ktype]*dwik)/rikmag; fi[0] -= tmp2*rik[0]; fi[1] -= tmp2*rik[1]; fi[2] -= tmp2*rik[2]; fk[0] += tmp2*rik[0]; fk[1] += tmp2*rik[1]; fk[2] += tmp2*rik[2]; // dgdN forces tmp2 = VA*.5*(tmp*tmp3*dwik)/rikmag; fi[0] -= tmp2*rik[0]; fi[1] -= tmp2*rik[1]; fi[2] -= tmp2*rik[2]; fk[0] += tmp2*rik[0]; fk[1] += tmp2*rik[1]; fk[2] += tmp2*rik[2]; f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2]; f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2]; f[atomk][0] += fk[0]; f[atomk][1] += fk[1]; f[atomk][2] += fk[2]; if (vflag_atom) { rji[0] = -rij[0]; rji[1] = -rij[1]; rji[2] = -rij[2]; rki[0] = -rik[0]; rki[1] = -rik[1]; rki[2] = -rik[2]; v_tally3(atomi,atomj,atomk,fj,fk,rji,rki); } } } tmp = 0.0; tmp2 = 0.0; tmp3 = 0.0; Etmp = 0.0; REBO_neighs = REBO_firstneigh[j]; for (l = 0; l < REBO_numneigh[j]; l++) { atoml = REBO_neighs[l]; if (atoml != atomi) { ltype = map[type[atoml]]; rjl[0] = x[atomj][0]-x[atoml][0]; rjl[1] = x[atomj][1]-x[atoml][1]; rjl[2] = x[atomj][2]-x[atoml][2]; rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2])); lamdaijl = 4.0*kronecker(jtype,1) * ((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag)); wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dS); Nlj = nC[atoml]-(wjl*kronecker(jtype,0)) + nH[atoml]-(wjl*kronecker(jtype,1)); cosijl = -1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])) / (rijmag*rjlmag); cosijl = MIN(cosijl,1.0); cosijl = MAX(cosijl,-1.0); // evaluate splines g and derivatives dg g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN); Etmp = Etmp+(wjl*g*exp(lamdaijl)); tmp3 = tmp3+(wjl*dgdN*exp(lamdaijl)); NconjtmpJ = NconjtmpJ+(kronecker(ltype,0)*wjl*Sp(Nlj,Nmin,Nmax,dS)); } } PjiS = 0.0; dN2[0] = 0.0; dN2[1] = 0.0; PjiS = PijSpline(NjiC,NjiH,jtype,itype,dN2); pji = pow(1.0+Etmp+PjiS,-0.5); tmp = -0.5*cube(pji); REBO_neighs = REBO_firstneigh[j]; for (l = 0; l < REBO_numneigh[j]; l++) { atoml = REBO_neighs[l]; if (atoml != atomi) { ltype = map[type[atoml]]; rjl[0] = x[atomj][0]-x[atoml][0]; rjl[1] = x[atomj][1]-x[atoml][1]; rjl[2] = x[atomj][2]-x[atoml][2]; rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2])); lamdaijl = 4.0*kronecker(jtype,1) * ((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag)); wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl); cosijl = (-1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2]))) / (rijmag*rjlmag); cosijl = MIN(cosijl,1.0); cosijl = MAX(cosijl,-1.0); dcosijldri[0] = (-rjl[0]/(rijmag*rjlmag)) - (cosijl*rij[0]/(rijmag*rijmag)); dcosijldri[1] = (-rjl[1]/(rijmag*rjlmag)) - (cosijl*rij[1]/(rijmag*rijmag)); dcosijldri[2] = (-rjl[2]/(rijmag*rjlmag)) - (cosijl*rij[2]/(rijmag*rijmag)); dcosijldrj[0] = ((-rij[0]+rjl[0])/(rijmag*rjlmag)) + (cosijl*((rij[0]/square(rijmag))-(rjl[0]/(rjlmag*rjlmag)))); dcosijldrj[1] = ((-rij[1]+rjl[1])/(rijmag*rjlmag)) + (cosijl*((rij[1]/square(rijmag))-(rjl[1]/(rjlmag*rjlmag)))); dcosijldrj[2] = ((-rij[2]+rjl[2])/(rijmag*rjlmag)) + (cosijl*((rij[2]/square(rijmag))-(rjl[2]/(rjlmag*rjlmag)))); dcosijldrl[0] = (rij[0]/(rijmag*rjlmag))+(cosijl*rjl[0]/(rjlmag*rjlmag)); dcosijldrl[1] = (rij[1]/(rijmag*rjlmag))+(cosijl*rjl[1]/(rjlmag*rjlmag)); dcosijldrl[2] = (rij[2]/(rijmag*rjlmag))+(cosijl*rjl[2]/(rjlmag*rjlmag)); // evaluate splines g and derivatives dg g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN); tmp2 = VA*.5*(tmp*wjl*dgdc*exp(lamdaijl)); fi[0] = -tmp2*dcosijldri[0]; fi[1] = -tmp2*dcosijldri[1]; fi[2] = -tmp2*dcosijldri[2]; fj[0] = -tmp2*dcosijldrj[0]; fj[1] = -tmp2*dcosijldrj[1]; fj[2] = -tmp2*dcosijldrj[2]; fl[0] = -tmp2*dcosijldrl[0]; fl[1] = -tmp2*dcosijldrl[1]; fl[2] = -tmp2*dcosijldrl[2]; tmp2 = VA*.5*(tmp*wjl*g*exp(lamdaijl)*4.0*kronecker(jtype,1)); fi[0] -= tmp2*(rij[0]/rijmag); fi[1] -= tmp2*(rij[1]/rijmag); fi[2] -= tmp2*(rij[2]/rijmag); fj[0] -= tmp2*((-rjl[0]/rjlmag)-(rij[0]/rijmag)); fj[1] -= tmp2*((-rjl[1]/rjlmag)-(rij[1]/rijmag)); fj[2] -= tmp2*((-rjl[2]/rjlmag)-(rij[2]/rijmag)); fl[0] -= tmp2*(rjl[0]/rjlmag); fl[1] -= tmp2*(rjl[1]/rjlmag); fl[2] -= tmp2*(rjl[2]/rjlmag); // coordination forces // dwik forces tmp2 = VA*.5*(tmp*dwjl*g*exp(lamdaijl))/rjlmag; fj[0] -= tmp2*rjl[0]; fj[1] -= tmp2*rjl[1]; fj[2] -= tmp2*rjl[2]; fl[0] += tmp2*rjl[0]; fl[1] += tmp2*rjl[1]; fl[2] += tmp2*rjl[2]; // PIJ forces tmp2 = VA*.5*(tmp*dN2[ltype]*dwjl)/rjlmag; fj[0] -= tmp2*rjl[0]; fj[1] -= tmp2*rjl[1]; fj[2] -= tmp2*rjl[2]; fl[0] += tmp2*rjl[0]; fl[1] += tmp2*rjl[1]; fl[2] += tmp2*rjl[2]; // dgdN forces tmp2 = VA*.5*(tmp*tmp3*dwjl)/rjlmag; fj[0] -= tmp2*rjl[0]; fj[1] -= tmp2*rjl[1]; fj[2] -= tmp2*rjl[2]; fl[0] += tmp2*rjl[0]; fl[1] += tmp2*rjl[1]; fl[2] += tmp2*rjl[2]; f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2]; f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2]; f[atoml][0] += fl[0]; f[atoml][1] += fl[1]; f[atoml][2] += fl[2]; if (vflag_atom) { rlj[0] = -rjl[0]; rlj[1] = -rjl[1]; rlj[2] = -rjl[2]; v_tally3(atomi,atomj,atoml,fi,fl,rij,rlj); } } } // evaluate Nij conj Nijconj = 1.0+(NconjtmpI*NconjtmpI)+(NconjtmpJ*NconjtmpJ); piRC = piRCSpline(NijC+NijH,NjiC+NjiH,Nijconj,itype,jtype,dN3); // piRC forces REBO_neighs_i = REBO_firstneigh[i]; for (k = 0; k < REBO_numneigh[i]; k++) { atomk = REBO_neighs_i[k]; if (atomk !=atomj) { ktype = map[type[atomk]]; rik[0] = x[atomi][0]-x[atomk][0]; rik[1] = x[atomi][1]-x[atomk][1]; rik[2] = x[atomi][2]-x[atomk][2]; rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2])); wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik); Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] - (wik*kronecker(itype,1)); SpN = Sp(Nki,Nmin,Nmax,dNki); tmp2 = VA*dN3[0]*dwik/rikmag; f[atomi][0] -= tmp2*rik[0]; f[atomi][1] -= tmp2*rik[1]; f[atomi][2] -= tmp2*rik[2]; f[atomk][0] += tmp2*rik[0]; f[atomk][1] += tmp2*rik[1]; f[atomk][2] += tmp2*rik[2]; if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik); tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)/rikmag; f[atomi][0] -= tmp2*rik[0]; f[atomi][1] -= tmp2*rik[1]; f[atomi][2] -= tmp2*rik[2]; f[atomk][0] += tmp2*rik[0]; f[atomk][1] += tmp2*rik[1]; f[atomk][2] += tmp2*rik[2]; if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik); if (fabs(dNki) > TOL) { REBO_neighs_k = REBO_firstneigh[atomk]; for (n = 0; n < REBO_numneigh[atomk]; n++) { atomn = REBO_neighs_k[n]; if (atomn != atomi) { ntype = map[type[atomn]]; rkn[0] = x[atomk][0]-x[atomn][0]; rkn[1] = x[atomk][1]-x[atomn][1]; rkn[2] = x[atomk][2]-x[atomn][2]; rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2])); Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn); tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)/rknmag; f[atomk][0] -= tmp2*rkn[0]; f[atomk][1] -= tmp2*rkn[1]; f[atomk][2] -= tmp2*rkn[2]; f[atomn][0] += tmp2*rkn[0]; f[atomn][1] += tmp2*rkn[1]; f[atomn][2] += tmp2*rkn[2]; if (vflag_atom) v_tally2(atomk,atomn,-tmp2,rkn); } } } } } // piRC forces REBO_neighs = REBO_firstneigh[atomj]; for (l = 0; l < REBO_numneigh[atomj]; l++) { atoml = REBO_neighs[l]; if (atoml !=atomi) { ltype = map[type[atoml]]; rjl[0] = x[atomj][0]-x[atoml][0]; rjl[1] = x[atomj][1]-x[atoml][1]; rjl[2] = x[atomj][2]-x[atoml][2]; rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2])); wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl); Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] - (wjl*kronecker(jtype,1)); SpN = Sp(Nlj,Nmin,Nmax,dNlj); tmp2 = VA*dN3[1]*dwjl/rjlmag; f[atomj][0] -= tmp2*rjl[0]; f[atomj][1] -= tmp2*rjl[1]; f[atomj][2] -= tmp2*rjl[2]; f[atoml][0] += tmp2*rjl[0]; f[atoml][1] += tmp2*rjl[1]; f[atoml][2] += tmp2*rjl[2]; if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl); tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)/rjlmag; f[atomj][0] -= tmp2*rjl[0]; f[atomj][1] -= tmp2*rjl[1]; f[atomj][2] -= tmp2*rjl[2]; f[atoml][0] += tmp2*rjl[0]; f[atoml][1] += tmp2*rjl[1]; f[atoml][2] += tmp2*rjl[2]; if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl); if (fabs(dNlj) > TOL) { REBO_neighs_l = REBO_firstneigh[atoml]; for (n = 0; n < REBO_numneigh[atoml]; n++) { atomn = REBO_neighs_l[n]; if (atomn != atomj) { ntype = map[type[atomn]]; rln[0] = x[atoml][0]-x[atomn][0]; rln[1] = x[atoml][1]-x[atomn][1]; rln[2] = x[atoml][2]-x[atomn][2]; rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2])); Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln); tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)/rlnmag; f[atoml][0] -= tmp2*rln[0]; f[atoml][1] -= tmp2*rln[1]; f[atoml][2] -= tmp2*rln[2]; f[atomn][0] += tmp2*rln[0]; f[atomn][1] += tmp2*rln[1]; f[atomn][2] += tmp2*rln[2]; if (vflag_atom) v_tally2(atoml,atomn,-tmp2,rln); } } } } } Tij = 0.0; dN3[0] = 0.0; dN3[1] = 0.0; dN3[2] = 0.0; if (itype == 0 && jtype == 0) Tij=TijSpline((NijC+NijH),(NjiC+NjiH),Nijconj,dN3); Etmp = 0.0; if (fabs(Tij) > TOL) { atom2 = atomi; atom3 = atomj; r32[0] = x[atom3][0]-x[atom2][0]; r32[1] = x[atom3][1]-x[atom2][1]; r32[2] = x[atom3][2]-x[atom2][2]; r32mag = sqrt((r32[0]*r32[0])+(r32[1]*r32[1])+(r32[2]*r32[2])); r23[0] = -r32[0]; r23[1] = -r32[1]; r23[2] = -r32[2]; r23mag = r32mag; REBO_neighs_i = REBO_firstneigh[i]; for (k = 0; k < REBO_numneigh[i]; k++) { atomk = REBO_neighs_i[k]; atom1 = atomk; ktype = map[type[atomk]]; if (atomk != atomj) { r21[0] = x[atom2][0]-x[atom1][0]; r21[1] = x[atom2][1]-x[atom1][1]; r21[2] = x[atom2][2]-x[atom1][2]; r21mag = sqrt(r21[0]*r21[0] + r21[1]*r21[1] + r21[2]*r21[2]); cos321 = -1.0*((r21[0]*r32[0])+(r21[1]*r32[1])+(r21[2]*r32[2])) / (r21mag*r32mag); cos321 = MIN(cos321,1.0); cos321 = MAX(cos321,-1.0); Sp2(cos321,thmin,thmax,dcut321); sin321 = sqrt(1.0 - cos321*cos321); if ((sin321 > TOL) && (r21mag > TOL)) { // XXX was sin321 != 0.0 sink2i = 1.0/(sin321*sin321); rik2i = 1.0/(r21mag*r21mag); rr = (r23mag*r23mag)-(r21mag*r21mag); rjk[0] = r21[0]-r23[0]; rjk[1] = r21[1]-r23[1]; rjk[2] = r21[2]-r23[2]; rjk2 = (rjk[0]*rjk[0])+(rjk[1]*rjk[1])+(rjk[2]*rjk[2]); rijrik = 2.0*r23mag*r21mag; rik2 = r21mag*r21mag; dctik = (-rr+rjk2)/(rijrik*rik2); dctij = (rr+rjk2)/(rijrik*r23mag*r23mag); dctjk = -2.0/rijrik; w21 = Sp(r21mag,rcmin[itype][ktype],rcmaxp[itype][ktype],dw21); rijmag = r32mag; rikmag = r21mag; rij2 = r32mag*r32mag; rik2 = r21mag*r21mag; costmp = 0.5*(rij2+rik2-rjk2)/rijmag/rikmag; tspjik = Sp2(costmp,thmin,thmax,dtsjik); dtsjik = -dtsjik; REBO_neighs_j = REBO_firstneigh[j]; for (l = 0; l < REBO_numneigh[j]; l++) { atoml = REBO_neighs_j[l]; atom4 = atoml; ltype = map[type[atoml]]; if (!(atoml == atomi || atoml == atomk)) { r34[0] = x[atom3][0]-x[atom4][0]; r34[1] = x[atom3][1]-x[atom4][1]; r34[2] = x[atom3][2]-x[atom4][2]; r34mag = sqrt((r34[0]*r34[0])+(r34[1]*r34[1])+(r34[2]*r34[2])); cos234 = (r32[0]*r34[0] + r32[1]*r34[1] + r32[2]*r34[2]) / (r32mag*r34mag); cos234 = MIN(cos234,1.0); cos234 = MAX(cos234,-1.0); sin234 = sqrt(1.0 - cos234*cos234); if ((sin234 > TOL) && (r34mag > TOL)) { // XXX was sin234 != 0.0 sinl2i = 1.0/(sin234*sin234); rjl2i = 1.0/(r34mag*r34mag); w34 = Sp(r34mag,rcmin[jtype][ltype],rcmaxp[jtype][ltype],dw34); rr = (r23mag*r23mag)-(r34mag*r34mag); ril[0] = r23[0]+r34[0]; ril[1] = r23[1]+r34[1]; ril[2] = r23[2]+r34[2]; ril2 = (ril[0]*ril[0])+(ril[1]*ril[1])+(ril[2]*ril[2]); rijrjl = 2.0*r23mag*r34mag; rjl2 = r34mag*r34mag; dctjl = (-rr+ril2)/(rijrjl*rjl2); dctji = (rr+ril2)/(rijrjl*r23mag*r23mag); dctil = -2.0/rijrjl; rjlmag = r34mag; rjl2 = r34mag*r34mag; costmp = 0.5*(rij2+rjl2-ril2)/rijmag/rjlmag; tspijl = Sp2(costmp,thmin,thmax,dtsijl); dtsijl = -dtsijl; prefactor = VA*Tij; cross321[0] = (r32[1]*r21[2])-(r32[2]*r21[1]); cross321[1] = (r32[2]*r21[0])-(r32[0]*r21[2]); cross321[2] = (r32[0]*r21[1])-(r32[1]*r21[0]); cross234[0] = (r23[1]*r34[2])-(r23[2]*r34[1]); cross234[1] = (r23[2]*r34[0])-(r23[0]*r34[2]); cross234[2] = (r23[0]*r34[1])-(r23[1]*r34[0]); cwnum = (cross321[0]*cross234[0]) + (cross321[1]*cross234[1]) + (cross321[2]*cross234[2]); cwnom = r21mag*r34mag*r23mag*r23mag*sin321*sin234; om1234 = cwnum/cwnom; cw = om1234; Etmp += ((1.0-square(om1234))*w21*w34) * (1.0-tspjik)*(1.0-tspijl); dt1dik = (rik2i)-(dctik*sink2i*cos321); dt1djk = (-dctjk*sink2i*cos321); dt1djl = (rjl2i)-(dctjl*sinl2i*cos234); dt1dil = (-dctil*sinl2i*cos234); dt1dij = (2.0/(r23mag*r23mag))-(dctij*sink2i*cos321) - (dctji*sinl2i*cos234); dt2dik[0] = (-r23[2]*cross234[1])+(r23[1]*cross234[2]); dt2dik[1] = (-r23[0]*cross234[2])+(r23[2]*cross234[0]); dt2dik[2] = (-r23[1]*cross234[0])+(r23[0]*cross234[1]); dt2djl[0] = (-r23[1]*cross321[2])+(r23[2]*cross321[1]); dt2djl[1] = (-r23[2]*cross321[0])+(r23[0]*cross321[2]); dt2djl[2] = (-r23[0]*cross321[1])+(r23[1]*cross321[0]); dt2dij[0] = (r21[2]*cross234[1])-(r34[2]*cross321[1]) - (r21[1]*cross234[2])+(r34[1]*cross321[2]); dt2dij[1] = (r21[0]*cross234[2])-(r34[0]*cross321[2]) - (r21[2]*cross234[0])+(r34[2]*cross321[0]); dt2dij[2] = (r21[1]*cross234[0])-(r34[1]*cross321[0]) - (r21[0]*cross234[1])+(r34[0]*cross321[1]); aa = (prefactor*2.0*cw/cwnom)*w21*w34 * (1.0-tspjik)*(1.0-tspijl); aaa1 = -prefactor*(1.0-square(om1234)) * (1.0-tspjik)*(1.0-tspijl); aaa2 = aaa1*w21*w34; at2 = aa*cwnum; fcijpc = (-dt1dij*at2)+(aaa2*dtsjik*dctij*(1.0-tspijl)) + (aaa2*dtsijl*dctji*(1.0-tspjik)); fcikpc = (-dt1dik*at2)+(aaa2*dtsjik*dctik*(1.0-tspijl)); fcjlpc = (-dt1djl*at2)+(aaa2*dtsijl*dctjl*(1.0-tspjik)); fcjkpc = (-dt1djk*at2)+(aaa2*dtsjik*dctjk*(1.0-tspijl)); fcilpc = (-dt1dil*at2)+(aaa2*dtsijl*dctil*(1.0-tspjik)); F23[0] = (fcijpc*r23[0])+(aa*dt2dij[0]); F23[1] = (fcijpc*r23[1])+(aa*dt2dij[1]); F23[2] = (fcijpc*r23[2])+(aa*dt2dij[2]); F12[0] = (fcikpc*r21[0])+(aa*dt2dik[0]); F12[1] = (fcikpc*r21[1])+(aa*dt2dik[1]); F12[2] = (fcikpc*r21[2])+(aa*dt2dik[2]); F34[0] = (fcjlpc*r34[0])+(aa*dt2djl[0]); F34[1] = (fcjlpc*r34[1])+(aa*dt2djl[1]); F34[2] = (fcjlpc*r34[2])+(aa*dt2djl[2]); F31[0] = (fcjkpc*rjk[0]); F31[1] = (fcjkpc*rjk[1]); F31[2] = (fcjkpc*rjk[2]); F24[0] = (fcilpc*ril[0]); F24[1] = (fcilpc*ril[1]); F24[2] = (fcilpc*ril[2]); f1[0] = -F12[0]-F31[0]; f1[1] = -F12[1]-F31[1]; f1[2] = -F12[2]-F31[2]; f2[0] = F23[0]+F12[0]+F24[0]; f2[1] = F23[1]+F12[1]+F24[1]; f2[2] = F23[2]+F12[2]+F24[2]; f3[0] = -F23[0]+F34[0]+F31[0]; f3[1] = -F23[1]+F34[1]+F31[1]; f3[2] = -F23[2]+F34[2]+F31[2]; f4[0] = -F34[0]-F24[0]; f4[1] = -F34[1]-F24[1]; f4[2] = -F34[2]-F24[2]; // coordination forces tmp2 = VA*Tij*((1.0-(om1234*om1234))) * (1.0-tspjik)*(1.0-tspijl)*dw21*w34/r21mag; f2[0] -= tmp2*r21[0]; f2[1] -= tmp2*r21[1]; f2[2] -= tmp2*r21[2]; f1[0] += tmp2*r21[0]; f1[1] += tmp2*r21[1]; f1[2] += tmp2*r21[2]; tmp2 = VA*Tij*((1.0-(om1234*om1234))) * (1.0-tspjik)*(1.0-tspijl)*w21*dw34/r34mag; f3[0] -= tmp2*r34[0]; f3[1] -= tmp2*r34[1]; f3[2] -= tmp2*r34[2]; f4[0] += tmp2*r34[0]; f4[1] += tmp2*r34[1]; f4[2] += tmp2*r34[2]; f[atom1][0] += f1[0]; f[atom1][1] += f1[1]; f[atom1][2] += f1[2]; f[atom2][0] += f2[0]; f[atom2][1] += f2[1]; f[atom2][2] += f2[2]; f[atom3][0] += f3[0]; f[atom3][1] += f3[1]; f[atom3][2] += f3[2]; f[atom4][0] += f4[0]; f[atom4][1] += f4[1]; f[atom4][2] += f4[2]; if (vflag_atom) { r13[0] = -rjk[0]; r13[1] = -rjk[1]; r13[2] = -rjk[2]; r43[0] = -r34[0]; r43[1] = -r34[1]; r43[2] = -r34[2]; v_tally4(atom1,atom2,atom3,atom4,f1,f2,f4,r13,r23,r43); } } } } } } } // Tij forces now that we have Etmp REBO_neighs = REBO_firstneigh[i]; for (k = 0; k < REBO_numneigh[i]; k++) { atomk = REBO_neighs[k]; if (atomk != atomj) { ktype = map[type[atomk]]; rik[0] = x[atomi][0]-x[atomk][0]; rik[1] = x[atomi][1]-x[atomk][1]; rik[2] = x[atomi][2]-x[atomk][2]; rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2])); wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik); Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] - (wik*kronecker(itype,1)); SpN = Sp(Nki,Nmin,Nmax,dNki); tmp2 = VA*dN3[0]*dwik*Etmp/rikmag; f[atomi][0] -= tmp2*rik[0]; f[atomi][1] -= tmp2*rik[1]; f[atomi][2] -= tmp2*rik[2]; f[atomk][0] += tmp2*rik[0]; f[atomk][1] += tmp2*rik[1]; f[atomk][2] += tmp2*rik[2]; if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik); tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)*Etmp/rikmag; f[atomi][0] -= tmp2*rik[0]; f[atomi][1] -= tmp2*rik[1]; f[atomi][2] -= tmp2*rik[2]; f[atomk][0] += tmp2*rik[0]; f[atomk][1] += tmp2*rik[1]; f[atomk][2] += tmp2*rik[2]; if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik); if (fabs(dNki) > TOL) { REBO_neighs_k = REBO_firstneigh[atomk]; for (n = 0; n < REBO_numneigh[atomk]; n++) { atomn = REBO_neighs_k[n]; ntype = map[type[atomn]]; if (atomn != atomi) { rkn[0] = x[atomk][0]-x[atomn][0]; rkn[1] = x[atomk][1]-x[atomn][1]; rkn[2] = x[atomk][2]-x[atomn][2]; rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2])); Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn); tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)*Etmp/rknmag; f[atomk][0] -= tmp2*rkn[0]; f[atomk][1] -= tmp2*rkn[1]; f[atomk][2] -= tmp2*rkn[2]; f[atomn][0] += tmp2*rkn[0]; f[atomn][1] += tmp2*rkn[1]; f[atomn][2] += tmp2*rkn[2]; if (vflag_atom) v_tally2(atomk,atomn,-tmp2,rkn); } } } } } // Tij forces REBO_neighs = REBO_firstneigh[j]; for (l = 0; l < REBO_numneigh[j]; l++) { atoml = REBO_neighs[l]; if (atoml != atomi) { ltype = map[type[atoml]]; rjl[0] = x[atomj][0]-x[atoml][0]; rjl[1] = x[atomj][1]-x[atoml][1]; rjl[2] = x[atomj][2]-x[atoml][2]; rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2])); wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl); Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] - (wjl*kronecker(jtype,1)); SpN = Sp(Nlj,Nmin,Nmax,dNlj); tmp2 = VA*dN3[1]*dwjl*Etmp/rjlmag; f[atomj][0] -= tmp2*rjl[0]; f[atomj][1] -= tmp2*rjl[1]; f[atomj][2] -= tmp2*rjl[2]; f[atoml][0] += tmp2*rjl[0]; f[atoml][1] += tmp2*rjl[1]; f[atoml][2] += tmp2*rjl[2]; if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl); tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)*Etmp/rjlmag; f[atomj][0] -= tmp2*rjl[0]; f[atomj][1] -= tmp2*rjl[1]; f[atomj][2] -= tmp2*rjl[2]; f[atoml][0] += tmp2*rjl[0]; f[atoml][1] += tmp2*rjl[1]; f[atoml][2] += tmp2*rjl[2]; if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl); if (fabs(dNlj) > TOL) { REBO_neighs_l = REBO_firstneigh[atoml]; for (n = 0; n < REBO_numneigh[atoml]; n++) { atomn = REBO_neighs_l[n]; ntype = map[type[atomn]]; if (atomn !=atomj) { rln[0] = x[atoml][0]-x[atomn][0]; rln[1] = x[atoml][1]-x[atomn][1]; rln[2] = x[atoml][2]-x[atomn][2]; rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2])); Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln); tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)*Etmp/rlnmag; f[atoml][0] -= tmp2*rln[0]; f[atoml][1] -= tmp2*rln[1]; f[atoml][2] -= tmp2*rln[2]; f[atomn][0] += tmp2*rln[0]; f[atomn][1] += tmp2*rln[1]; f[atomn][2] += tmp2*rln[2]; if (vflag_atom) v_tally2(atoml,atomn,-tmp2,rln); } } } } } } bij = (0.5*(pij+pji))+piRC+(Tij*Etmp); return bij; } /* ---------------------------------------------------------------------- Bij* function ------------------------------------------------------------------------- */ double PairAIREBO::bondorderLJ(int i, int j, double rij[3], double rijmag, double VA, double rij0[3], double rij0mag, double **f, int vflag_atom) { int k,n,l,atomk,atoml,atomn,atom1,atom2,atom3,atom4; int atomi,atomj,itype,jtype,ktype,ltype,ntype; double rik[3], rjl[3], rkn[3],rknmag,dNki; double NijC,NijH,NjiC,NjiH,wik,dwik,dwkn,wjl; double rikmag,rjlmag,cosjik,cosijl,g,tmp2,tmp3; double Etmp,pij,tmp,wij,dwij,NconjtmpI,NconjtmpJ; double Nki,Nlj,dS,lamdajik,lamdaijl,dgdc,dgdN,pji,Nijconj,piRC; double dcosjikdri[3],dcosijldri[3],dcosjikdrk[3]; double dN2[2],dN3[3]; double dcosijldrj[3],dcosijldrl[3],dcosjikdrj[3],dwjl; double Tij,crosskij[3],crosskijmag; double crossijl[3],crossijlmag,omkijl; double tmppij,tmppji,dN2PIJ[2],dN2PJI[2],dN3piRC[3],dN3Tij[3]; double bij,tmp3pij,tmp3pji,Stb,dStb; double r32[3],r32mag,cos321; double om1234,rln[3]; double rlnmag,dwln,r23[3],r23mag,r21[3],r21mag; double w21,dw21,r34[3],r34mag,cos234,w34,dw34; double cross321[3],cross234[3],prefactor,SpN; double fcijpc,fcikpc,fcjlpc,fcjkpc,fcilpc; double dt2dik[3],dt2djl[3],dt2dij[3],aa,aaa1,aaa2,at2,cw,cwnum,cwnom; double sin321,sin234,rr,rijrik,rijrjl,rjk2,rik2,ril2,rjl2; double dctik,dctjk,dctjl,dctij,dctji,dctil,rik2i,rjl2i,sink2i,sinl2i; double rjk[3],ril[3],dt1dik,dt1djk,dt1djl,dt1dil,dt1dij; double dNlj; double PijS,PjiS; double rij2,tspjik,dtsjik,tspijl,dtsijl,costmp; int *REBO_neighs,*REBO_neighs_i,*REBO_neighs_j,*REBO_neighs_k,*REBO_neighs_l; double F12[3],F23[3],F34[3],F31[3],F24[3]; double fi[3],fj[3],fk[3],fl[3],f1[3],f2[3],f3[3],f4[4]; double rji[3],rki[3],rlj[3],r13[3],r43[3]; double **x = atom->x; int *type = atom->type; atomi = i; atomj = j; itype = map[type[atomi]]; jtype = map[type[atomj]]; wij = Sp(rij0mag,rcmin[itype][jtype],rcmax[itype][jtype],dwij); NijC = nC[atomi]-(wij*kronecker(jtype,0)); NijH = nH[atomi]-(wij*kronecker(jtype,1)); NjiC = nC[atomj]-(wij*kronecker(itype,0)); NjiH = nH[atomj]-(wij*kronecker(itype,1)); bij = 0.0; tmp = 0.0; tmp2 = 0.0; tmp3 = 0.0; dgdc = 0.0; dgdN = 0.0; NconjtmpI = 0.0; NconjtmpJ = 0.0; Etmp = 0.0; Stb = 0.0; dStb = 0.0; REBO_neighs = REBO_firstneigh[i]; for (k = 0; k < REBO_numneigh[i]; k++) { atomk = REBO_neighs[k]; if (atomk != atomj) { ktype = map[type[atomk]]; rik[0] = x[atomi][0]-x[atomk][0]; rik[1] = x[atomi][1]-x[atomk][1]; rik[2] = x[atomi][2]-x[atomk][2]; rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2])); lamdajik = 4.0*kronecker(itype,1) * ((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag)); wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dS); Nki = nC[atomk]-(wik*kronecker(itype,0)) + nH[atomk]-(wik*kronecker(itype,1)); cosjik = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) / (rijmag*rikmag); cosjik = MIN(cosjik,1.0); cosjik = MAX(cosjik,-1.0); // evaluate splines g and derivatives dg g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN); Etmp += (wik*g*exp(lamdajik)); tmp3 += (wik*dgdN*exp(lamdajik)); NconjtmpI = NconjtmpI+(kronecker(ktype,0)*wik*Sp(Nki,Nmin,Nmax,dS)); } } PijS = 0.0; dN2PIJ[0] = 0.0; dN2PIJ[1] = 0.0; PijS = PijSpline(NijC,NijH,itype,jtype,dN2PIJ); pij = pow(1.0+Etmp+PijS,-0.5); tmppij = -.5*cube(pij); tmp3pij = tmp3; tmp = 0.0; tmp2 = 0.0; tmp3 = 0.0; Etmp = 0.0; REBO_neighs = REBO_firstneigh[j]; for (l = 0; l < REBO_numneigh[j]; l++) { atoml = REBO_neighs[l]; if (atoml != atomi) { ltype = map[type[atoml]]; rjl[0] = x[atomj][0]-x[atoml][0]; rjl[1] = x[atomj][1]-x[atoml][1]; rjl[2] = x[atomj][2]-x[atoml][2]; rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2])); lamdaijl = 4.0*kronecker(jtype,1) * ((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag)); wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dS); Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] - (wjl*kronecker(jtype,1)); cosijl = -1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])) / (rijmag*rjlmag); cosijl = MIN(cosijl,1.0); cosijl = MAX(cosijl,-1.0); // evaluate splines g and derivatives dg g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN); Etmp += (wjl*g*exp(lamdaijl)); tmp3 += (wjl*dgdN*exp(lamdaijl)); NconjtmpJ = NconjtmpJ+(kronecker(ltype,0)*wjl*Sp(Nlj,Nmin,Nmax,dS)); } } PjiS = 0.0; dN2PJI[0] = 0.0; dN2PJI[1] = 0.0; PjiS = PijSpline(NjiC,NjiH,jtype,itype,dN2PJI); pji = pow(1.0+Etmp+PjiS,-0.5); tmppji = -.5*cube(pji); tmp3pji = tmp3; // evaluate Nij conj Nijconj = 1.0+(NconjtmpI*NconjtmpI)+(NconjtmpJ*NconjtmpJ); piRC = piRCSpline(NijC+NijH,NjiC+NjiH,Nijconj,itype,jtype,dN3piRC); Tij = 0.0; dN3Tij[0] = 0.0; dN3Tij[1] = 0.0; dN3Tij[2] = 0.0; if (itype == 0 && jtype == 0) Tij=TijSpline((NijC+NijH),(NjiC+NjiH),Nijconj,dN3Tij); Etmp = 0.0; if (fabs(Tij) > TOL) { REBO_neighs_i = REBO_firstneigh[i]; for (k = 0; k < REBO_numneigh[i]; k++) { atomk = REBO_neighs_i[k]; ktype = map[type[atomk]]; if (atomk != atomj) { rik[0] = x[atomi][0]-x[atomk][0]; rik[1] = x[atomi][1]-x[atomk][1]; rik[2] = x[atomi][2]-x[atomk][2]; rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2])); cos321 = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) / (rijmag*rikmag); cos321 = MIN(cos321,1.0); cos321 = MAX(cos321,-1.0); rjk[0] = rik[0]-rij[0]; rjk[1] = rik[1]-rij[1]; rjk[2] = rik[2]-rij[2]; rjk2 = (rjk[0]*rjk[0])+(rjk[1]*rjk[1])+(rjk[2]*rjk[2]); rij2 = rijmag*rijmag; rik2 = rikmag*rikmag; costmp = 0.5*(rij2+rik2-rjk2)/rijmag/rikmag; tspjik = Sp2(costmp,thmin,thmax,dtsjik); if (sqrt(1.0 - cos321*cos321) > sqrt(TOL)) { wik = Sp(rikmag,rcmin[itype][ktype],rcmaxp[itype][ktype],dwik); REBO_neighs_j = REBO_firstneigh[j]; for (l = 0; l < REBO_numneigh[j]; l++) { atoml = REBO_neighs_j[l]; ltype = map[type[atoml]]; if (!(atoml == atomi || atoml == atomk)) { rjl[0] = x[atomj][0]-x[atoml][0]; rjl[1] = x[atomj][1]-x[atoml][1]; rjl[2] = x[atomj][2]-x[atoml][2]; rjlmag = sqrt(rjl[0]*rjl[0] + rjl[1]*rjl[1] + rjl[2]*rjl[2]); cos234 = -((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])) / (rijmag*rjlmag); cos234 = MIN(cos234,1.0); cos234 = MAX(cos234,-1.0); ril[0] = rij[0]+rjl[0]; ril[1] = rij[1]+rjl[1]; ril[2] = rij[2]+rjl[2]; ril2 = (ril[0]*ril[0])+(ril[1]*ril[1])+(ril[2]*ril[2]); rjl2 = rjlmag*rjlmag; costmp = 0.5*(rij2+rjl2-ril2)/rijmag/rjlmag; tspijl = Sp2(costmp,thmin,thmax,dtsijl); if (sqrt(1.0 - cos234*cos234) > sqrt(TOL)) { wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmaxp[jtype][ltype],dS); crosskij[0] = (rij[1]*rik[2]-rij[2]*rik[1]); crosskij[1] = (rij[2]*rik[0]-rij[0]*rik[2]); crosskij[2] = (rij[0]*rik[1]-rij[1]*rik[0]); crosskijmag = sqrt(crosskij[0]*crosskij[0] + crosskij[1]*crosskij[1] + crosskij[2]*crosskij[2]); crossijl[0] = (rij[1]*rjl[2]-rij[2]*rjl[1]); crossijl[1] = (rij[2]*rjl[0]-rij[0]*rjl[2]); crossijl[2] = (rij[0]*rjl[1]-rij[1]*rjl[0]); crossijlmag = sqrt(crossijl[0]*crossijl[0] + crossijl[1]*crossijl[1] + crossijl[2]*crossijl[2]); omkijl = -1.0*(((crosskij[0]*crossijl[0]) + (crosskij[1]*crossijl[1]) + (crosskij[2]*crossijl[2])) / (crosskijmag*crossijlmag)); Etmp += ((1.0-square(omkijl))*wik*wjl) * (1.0-tspjik)*(1.0-tspijl); } } } } } } } bij = (.5*(pij+pji))+piRC+(Tij*Etmp); Stb = Sp2(bij,bLJmin[itype][jtype],bLJmax[itype][jtype],dStb); VA = VA*dStb; if (dStb != 0.0) { tmp = tmppij; dN2[0] = dN2PIJ[0]; dN2[1] = dN2PIJ[1]; tmp3 = tmp3pij; // pij forces REBO_neighs_i = REBO_firstneigh[i]; for (k = 0; k < REBO_numneigh[i]; k++) { atomk = REBO_neighs_i[k]; ktype = map[type[atomk]]; if (atomk != atomj) { lamdajik = 0.0; rik[0] = x[atomi][0]-x[atomk][0]; rik[1] = x[atomi][1]-x[atomk][1]; rik[2] = x[atomi][2]-x[atomk][2]; rikmag = sqrt(rik[0]*rik[0] + rik[1]*rik[1] + rik[2]*rik[2]); lamdajik = 4.0*kronecker(itype,1) * ((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag)); wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik); cosjik = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) / (rijmag*rikmag); cosjik = MIN(cosjik,1.0); cosjik = MAX(cosjik,-1.0); dcosjikdri[0] = ((rij[0]+rik[0])/(rijmag*rikmag)) - (cosjik*((rij[0]/(rijmag*rijmag))+(rik[0]/(rikmag*rikmag)))); dcosjikdri[1] = ((rij[1]+rik[1])/(rijmag*rikmag)) - (cosjik*((rij[1]/(rijmag*rijmag))+(rik[1]/(rikmag*rikmag)))); dcosjikdri[2] = ((rij[2]+rik[2])/(rijmag*rikmag)) - (cosjik*((rij[2]/(rijmag*rijmag))+(rik[2]/(rikmag*rikmag)))); dcosjikdrk[0] = (-rij[0]/(rijmag*rikmag)) + (cosjik*(rik[0]/(rikmag*rikmag))); dcosjikdrk[1] = (-rij[1]/(rijmag*rikmag)) + (cosjik*(rik[1]/(rikmag*rikmag))); dcosjikdrk[2] = (-rij[2]/(rijmag*rikmag)) + (cosjik*(rik[2]/(rikmag*rikmag))); dcosjikdrj[0] = (-rik[0]/(rijmag*rikmag)) + (cosjik*(rij[0]/(rijmag*rijmag))); dcosjikdrj[1] = (-rik[1]/(rijmag*rikmag)) + (cosjik*(rij[1]/(rijmag*rijmag))); dcosjikdrj[2] = (-rik[2]/(rijmag*rikmag)) + (cosjik*(rij[2]/(rijmag*rijmag))); g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN); tmp2 = VA*.5*(tmp*wik*dgdc*exp(lamdajik)); fj[0] = -tmp2*dcosjikdrj[0]; fj[1] = -tmp2*dcosjikdrj[1]; fj[2] = -tmp2*dcosjikdrj[2]; fi[0] = -tmp2*dcosjikdri[0]; fi[1] = -tmp2*dcosjikdri[1]; fi[2] = -tmp2*dcosjikdri[2]; fk[0] = -tmp2*dcosjikdrk[0]; fk[1] = -tmp2*dcosjikdrk[1]; fk[2] = -tmp2*dcosjikdrk[2]; tmp2 = VA*.5*(tmp*wik*g*exp(lamdajik)*4.0*kronecker(itype,1)); fj[0] -= tmp2*(-rij[0]/rijmag); fj[1] -= tmp2*(-rij[1]/rijmag); fj[2] -= tmp2*(-rij[2]/rijmag); fi[0] -= tmp2*((-rik[0]/rikmag)+(rij[0]/rijmag)); fi[1] -= tmp2*((-rik[1]/rikmag)+(rij[1]/rijmag)); fi[2] -= tmp2*((-rik[2]/rikmag)+(rij[2]/rijmag)); fk[0] -= tmp2*(rik[0]/rikmag); fk[1] -= tmp2*(rik[1]/rikmag); fk[2] -= tmp2*(rik[2]/rikmag); // coordination forces // dwik forces tmp2 = VA*.5*(tmp*dwik*g*exp(lamdajik))/rikmag; fi[0] -= tmp2*rik[0]; fi[1] -= tmp2*rik[1]; fi[2] -= tmp2*rik[2]; fk[0] += tmp2*rik[0]; fk[1] += tmp2*rik[1]; fk[2] += tmp2*rik[2]; // PIJ forces tmp2 = VA*.5*(tmp*dN2[ktype]*dwik)/rikmag; fi[0] -= tmp2*rik[0]; fi[1] -= tmp2*rik[1]; fi[2] -= tmp2*rik[2]; fk[0] += tmp2*rik[0]; fk[1] += tmp2*rik[1]; fk[2] += tmp2*rik[2]; // dgdN forces tmp2 = VA*.5*(tmp*tmp3*dwik)/rikmag; fi[0] -= tmp2*rik[0]; fi[1] -= tmp2*rik[1]; fi[2] -= tmp2*rik[2]; fk[0] += tmp2*rik[0]; fk[1] += tmp2*rik[1]; fk[2] += tmp2*rik[2]; f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2]; f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2]; f[atomk][0] += fk[0]; f[atomk][1] += fk[1]; f[atomk][2] += fk[2]; if (vflag_atom) { rji[0] = -rij[0]; rji[1] = -rij[1]; rji[2] = -rij[2]; rki[0] = -rik[0]; rki[1] = -rik[1]; rki[2] = -rik[2]; v_tally3(atomi,atomj,atomk,fj,fk,rji,rki); } } } tmp = tmppji; tmp3 = tmp3pji; dN2[0] = dN2PJI[0]; dN2[1] = dN2PJI[1]; REBO_neighs = REBO_firstneigh[j]; for (l = 0; l < REBO_numneigh[j]; l++) { atoml = REBO_neighs[l]; if (atoml !=atomi) { ltype = map[type[atoml]]; rjl[0] = x[atomj][0]-x[atoml][0]; rjl[1] = x[atomj][1]-x[atoml][1]; rjl[2] = x[atomj][2]-x[atoml][2]; rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2])); lamdaijl = 4.0*kronecker(jtype,1) * ((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag)); wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl); cosijl = (-1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2]))) / (rijmag*rjlmag); cosijl = MIN(cosijl,1.0); cosijl = MAX(cosijl,-1.0); dcosijldri[0] = (-rjl[0]/(rijmag*rjlmag)) - (cosijl*rij[0]/(rijmag*rijmag)); dcosijldri[1] = (-rjl[1]/(rijmag*rjlmag)) - (cosijl*rij[1]/(rijmag*rijmag)); dcosijldri[2] = (-rjl[2]/(rijmag*rjlmag)) - (cosijl*rij[2]/(rijmag*rijmag)); dcosijldrj[0] = ((-rij[0]+rjl[0])/(rijmag*rjlmag)) + (cosijl*((rij[0]/square(rijmag))-(rjl[0]/(rjlmag*rjlmag)))); dcosijldrj[1] = ((-rij[1]+rjl[1])/(rijmag*rjlmag)) + (cosijl*((rij[1]/square(rijmag))-(rjl[1]/(rjlmag*rjlmag)))); dcosijldrj[2] = ((-rij[2]+rjl[2])/(rijmag*rjlmag)) + (cosijl*((rij[2]/square(rijmag))-(rjl[2]/(rjlmag*rjlmag)))); dcosijldrl[0] = (rij[0]/(rijmag*rjlmag)) + (cosijl*rjl[0]/(rjlmag*rjlmag)); dcosijldrl[1] = (rij[1]/(rijmag*rjlmag)) + (cosijl*rjl[1]/(rjlmag*rjlmag)); dcosijldrl[2] = (rij[2]/(rijmag*rjlmag)) + (cosijl*rjl[2]/(rjlmag*rjlmag)); // evaluate splines g and derivatives dg g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN); tmp2 = VA*.5*(tmp*wjl*dgdc*exp(lamdaijl)); fi[0] = -tmp2*dcosijldri[0]; fi[1] = -tmp2*dcosijldri[1]; fi[2] = -tmp2*dcosijldri[2]; fj[0] = -tmp2*dcosijldrj[0]; fj[1] = -tmp2*dcosijldrj[1]; fj[2] = -tmp2*dcosijldrj[2]; fl[0] = -tmp2*dcosijldrl[0]; fl[1] = -tmp2*dcosijldrl[1]; fl[2] = -tmp2*dcosijldrl[2]; tmp2 = VA*.5*(tmp*wjl*g*exp(lamdaijl)*4.0*kronecker(jtype,1)); fi[0] -= tmp2*(rij[0]/rijmag); fi[1] -= tmp2*(rij[1]/rijmag); fi[2] -= tmp2*(rij[2]/rijmag); fj[0] -= tmp2*((-rjl[0]/rjlmag)-(rij[0]/rijmag)); fj[1] -= tmp2*((-rjl[1]/rjlmag)-(rij[1]/rijmag)); fj[2] -= tmp2*((-rjl[2]/rjlmag)-(rij[2]/rijmag)); fl[0] -= tmp2*(rjl[0]/rjlmag); fl[1] -= tmp2*(rjl[1]/rjlmag); fl[2] -= tmp2*(rjl[2]/rjlmag); // coordination forces // dwik forces tmp2 = VA*.5*(tmp*dwjl*g*exp(lamdaijl))/rjlmag; fj[0] -= tmp2*rjl[0]; fj[1] -= tmp2*rjl[1]; fj[2] -= tmp2*rjl[2]; fl[0] += tmp2*rjl[0]; fl[1] += tmp2*rjl[1]; fl[2] += tmp2*rjl[2]; // PIJ forces tmp2 = VA*.5*(tmp*dN2[ltype]*dwjl)/rjlmag; fj[0] -= tmp2*rjl[0]; fj[1] -= tmp2*rjl[1]; fj[2] -= tmp2*rjl[2]; fl[0] += tmp2*rjl[0]; fl[1] += tmp2*rjl[1]; fl[2] += tmp2*rjl[2]; // dgdN forces tmp2=VA*.5*(tmp*tmp3*dwjl)/rjlmag; fj[0] -= tmp2*rjl[0]; fj[1] -= tmp2*rjl[1]; fj[2] -= tmp2*rjl[2]; fl[0] += tmp2*rjl[0]; fl[1] += tmp2*rjl[1]; fl[2] += tmp2*rjl[2]; f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2]; f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2]; f[atoml][0] += fl[0]; f[atoml][1] += fl[1]; f[atoml][2] += fl[2]; if (vflag_atom) { rlj[0] = -rjl[0]; rlj[1] = -rjl[1]; rlj[2] = -rjl[2]; v_tally3(atomi,atomj,atoml,fi,fl,rij,rlj); } } } // piRC forces dN3[0] = dN3piRC[0]; dN3[1] = dN3piRC[1]; dN3[2] = dN3piRC[2]; REBO_neighs_i = REBO_firstneigh[i]; for (k = 0; k < REBO_numneigh[i]; k++) { atomk = REBO_neighs_i[k]; if (atomk != atomj) { ktype = map[type[atomk]]; rik[0] = x[atomi][0]-x[atomk][0]; rik[1] = x[atomi][1]-x[atomk][1]; rik[2] = x[atomi][2]-x[atomk][2]; rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2])); wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik); Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] - (wik*kronecker(itype,1)); SpN = Sp(Nki,Nmin,Nmax,dNki); tmp2 = VA*dN3[0]*dwik/rikmag; f[atomi][0] -= tmp2*rik[0]; f[atomi][1] -= tmp2*rik[1]; f[atomi][2] -= tmp2*rik[2]; f[atomk][0] += tmp2*rik[0]; f[atomk][1] += tmp2*rik[1]; f[atomk][2] += tmp2*rik[2]; if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik); tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)/rikmag; f[atomi][0] -= tmp2*rik[0]; f[atomi][1] -= tmp2*rik[1]; f[atomi][2] -= tmp2*rik[2]; f[atomk][0] += tmp2*rik[0]; f[atomk][1] += tmp2*rik[1]; f[atomk][2] += tmp2*rik[2]; if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik); if (fabs(dNki) > TOL) { REBO_neighs_k = REBO_firstneigh[atomk]; for (n = 0; n < REBO_numneigh[atomk]; n++) { atomn = REBO_neighs_k[n]; if (atomn != atomi) { ntype = map[type[atomn]]; rkn[0] = x[atomk][0]-x[atomn][0]; rkn[1] = x[atomk][1]-x[atomn][1]; rkn[2] = x[atomk][2]-x[atomn][2]; rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2])); Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn); tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)/rknmag; f[atomk][0] -= tmp2*rkn[0]; f[atomk][1] -= tmp2*rkn[1]; f[atomk][2] -= tmp2*rkn[2]; f[atomn][0] += tmp2*rkn[0]; f[atomn][1] += tmp2*rkn[1]; f[atomn][2] += tmp2*rkn[2]; if (vflag_atom) v_tally2(atomk,atomn,-tmp2,rkn); } } } } } // piRC forces to J side REBO_neighs = REBO_firstneigh[j]; for (l = 0; l < REBO_numneigh[j]; l++) { atoml = REBO_neighs[l]; if (atoml != atomi) { ltype = map[type[atoml]]; rjl[0] = x[atomj][0]-x[atoml][0]; rjl[1] = x[atomj][1]-x[atoml][1]; rjl[2] = x[atomj][2]-x[atoml][2]; rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2])); wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl); Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] - (wjl*kronecker(jtype,1)); SpN = Sp(Nlj,Nmin,Nmax,dNlj); tmp2 = VA*dN3[1]*dwjl/rjlmag; f[atomj][0] -= tmp2*rjl[0]; f[atomj][1] -= tmp2*rjl[1]; f[atomj][2] -= tmp2*rjl[2]; f[atoml][0] += tmp2*rjl[0]; f[atoml][1] += tmp2*rjl[1]; f[atoml][2] += tmp2*rjl[2]; if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl); tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)/rjlmag; f[atomj][0] -= tmp2*rjl[0]; f[atomj][1] -= tmp2*rjl[1]; f[atomj][2] -= tmp2*rjl[2]; f[atoml][0] += tmp2*rjl[0]; f[atoml][1] += tmp2*rjl[1]; f[atoml][2] += tmp2*rjl[2]; if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl); if (fabs(dNlj) > TOL) { REBO_neighs_l = REBO_firstneigh[atoml]; for (n = 0; n < REBO_numneigh[atoml]; n++) { atomn = REBO_neighs_l[n]; if (atomn != atomj) { ntype = map[type[atomn]]; rln[0] = x[atoml][0]-x[atomn][0]; rln[1] = x[atoml][1]-x[atomn][1]; rln[2] = x[atoml][2]-x[atomn][2]; rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2])); Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln); tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)/rlnmag; f[atoml][0] -= tmp2*rln[0]; f[atoml][1] -= tmp2*rln[1]; f[atoml][2] -= tmp2*rln[2]; f[atomn][0] += tmp2*rln[0]; f[atomn][1] += tmp2*rln[1]; f[atomn][2] += tmp2*rln[2]; if (vflag_atom) v_tally2(atoml,atomn,-tmp2,rln); } } } } } if (fabs(Tij) > TOL) { dN3[0] = dN3Tij[0]; dN3[1] = dN3Tij[1]; dN3[2] = dN3Tij[2]; atom2 = atomi; atom3 = atomj; r32[0] = x[atom3][0]-x[atom2][0]; r32[1] = x[atom3][1]-x[atom2][1]; r32[2] = x[atom3][2]-x[atom2][2]; r32mag = sqrt((r32[0]*r32[0])+(r32[1]*r32[1])+(r32[2]*r32[2])); r23[0] = -r32[0]; r23[1] = -r32[1]; r23[2] = -r32[2]; r23mag = r32mag; REBO_neighs_i = REBO_firstneigh[i]; for (k = 0; k < REBO_numneigh[i]; k++) { atomk = REBO_neighs_i[k]; atom1 = atomk; ktype = map[type[atomk]]; if (atomk != atomj) { r21[0] = x[atom2][0]-x[atom1][0]; r21[1] = x[atom2][1]-x[atom1][1]; r21[2] = x[atom2][2]-x[atom1][2]; r21mag = sqrt(r21[0]*r21[0] + r21[1]*r21[1] + r21[2]*r21[2]); cos321 = ((r21[0]*rij[0])+(r21[1]*rij[1])+(r21[2]*rij[2])) / (r21mag*rijmag); cos321 = MIN(cos321,1.0); cos321 = MAX(cos321,-1.0); sin321 = sqrt(1.0 - cos321*cos321); if ((sin321 > TOL) && (r21mag > TOL)) { // XXX was sin321 != 0.0 sink2i = 1.0/(sin321*sin321); rik2i = 1.0/(r21mag*r21mag); rr = (rijmag*rijmag)-(r21mag*r21mag); rjk[0] = r21[0]-rij[0]; rjk[1] = r21[1]-rij[1]; rjk[2] = r21[2]-rij[2]; rjk2 = (rjk[0]*rjk[0])+(rjk[1]*rjk[1])+(rjk[2]*rjk[2]); rijrik = 2.0*rijmag*r21mag; rik2 = r21mag*r21mag; dctik = (-rr+rjk2)/(rijrik*rik2); dctij = (rr+rjk2)/(rijrik*rijmag*rijmag); dctjk = -2.0/rijrik; w21 = Sp(r21mag,rcmin[itype][ktype],rcmaxp[itype][ktype],dw21); rikmag = r21mag; rij2 = r32mag*r32mag; rik2 = r21mag*r21mag; costmp = 0.5*(rij2+rik2-rjk2)/rijmag/rikmag; tspjik = Sp2(costmp,thmin,thmax,dtsjik); dtsjik = -dtsjik; REBO_neighs_j = REBO_firstneigh[j]; for (l = 0; l < REBO_numneigh[j]; l++) { atoml = REBO_neighs_j[l]; atom4 = atoml; ltype = map[type[atoml]]; if (!(atoml == atomi || atoml == atomk)) { r34[0] = x[atom3][0]-x[atom4][0]; r34[1] = x[atom3][1]-x[atom4][1]; r34[2] = x[atom3][2]-x[atom4][2]; r34mag = sqrt(r34[0]*r34[0] + r34[1]*r34[1] + r34[2]*r34[2]); cos234 = -1.0*((rij[0]*r34[0])+(rij[1]*r34[1]) + (rij[2]*r34[2]))/(rijmag*r34mag); cos234 = MIN(cos234,1.0); cos234 = MAX(cos234,-1.0); sin234 = sqrt(1.0 - cos234*cos234); if ((sin234 > TOL) && (r34mag > TOL)) { // XXX was sin234 != 0.0 sinl2i = 1.0/(sin234*sin234); rjl2i = 1.0/(r34mag*r34mag); w34 = Sp(r34mag,rcmin[jtype][ltype], rcmaxp[jtype][ltype],dw34); rr = (r23mag*r23mag)-(r34mag*r34mag); ril[0] = r23[0]+r34[0]; ril[1] = r23[1]+r34[1]; ril[2] = r23[2]+r34[2]; ril2 = (ril[0]*ril[0])+(ril[1]*ril[1])+(ril[2]*ril[2]); rijrjl = 2.0*r23mag*r34mag; rjl2 = r34mag*r34mag; dctjl = (-rr+ril2)/(rijrjl*rjl2); dctji = (rr+ril2)/(rijrjl*r23mag*r23mag); dctil = -2.0/rijrjl; rjlmag = r34mag; rjl2 = r34mag*r34mag; costmp = 0.5*(rij2+rjl2-ril2)/rijmag/rjlmag; tspijl = Sp2(costmp,thmin,thmax,dtsijl); dtsijl = -dtsijl; //need minus sign prefactor = VA*Tij; cross321[0] = (r32[1]*r21[2])-(r32[2]*r21[1]); cross321[1] = (r32[2]*r21[0])-(r32[0]*r21[2]); cross321[2] = (r32[0]*r21[1])-(r32[1]*r21[0]); cross234[0] = (r23[1]*r34[2])-(r23[2]*r34[1]); cross234[1] = (r23[2]*r34[0])-(r23[0]*r34[2]); cross234[2] = (r23[0]*r34[1])-(r23[1]*r34[0]); cwnum = (cross321[0]*cross234[0]) + (cross321[1]*cross234[1])+(cross321[2]*cross234[2]); cwnom = r21mag*r34mag*r23mag*r23mag*sin321*sin234; om1234 = cwnum/cwnom; cw = om1234; Etmp += ((1.0-square(om1234))*w21*w34) * (1.0-tspjik)*(1.0-tspijl); dt1dik = (rik2i)-(dctik*sink2i*cos321); dt1djk = (-dctjk*sink2i*cos321); dt1djl = (rjl2i)-(dctjl*sinl2i*cos234); dt1dil = (-dctil*sinl2i*cos234); dt1dij = (2.0/(r23mag*r23mag)) - (dctij*sink2i*cos321)-(dctji*sinl2i*cos234); dt2dik[0] = (-r23[2]*cross234[1])+(r23[1]*cross234[2]); dt2dik[1] = (-r23[0]*cross234[2])+(r23[2]*cross234[0]); dt2dik[2] = (-r23[1]*cross234[0])+(r23[0]*cross234[1]); dt2djl[0] = (-r23[1]*cross321[2])+(r23[2]*cross321[1]); dt2djl[1] = (-r23[2]*cross321[0])+(r23[0]*cross321[2]); dt2djl[2] = (-r23[0]*cross321[1])+(r23[1]*cross321[0]); dt2dij[0] = (r21[2]*cross234[1]) - (r34[2]*cross321[1])-(r21[1]*cross234[2]) + (r34[1]*cross321[2]); dt2dij[1] = (r21[0]*cross234[2]) - (r34[0]*cross321[2])-(r21[2]*cross234[0]) + (r34[2]*cross321[0]); dt2dij[2] = (r21[1]*cross234[0]) - (r34[1]*cross321[0])-(r21[0]*cross234[1]) + (r34[0]*cross321[1]); aa = (prefactor*2.0*cw/cwnom)*w21*w34 * (1.0-tspjik)*(1.0-tspijl); aaa1 = -prefactor*(1.0-square(om1234)) * (1.0-tspjik)*(1.0-tspijl); aaa2 = aaa1*w21*w34; at2 = aa*cwnum; fcijpc = (-dt1dij*at2)+(aaa2*dtsjik*dctij*(1.0-tspijl)) + (aaa2*dtsijl*dctji*(1.0-tspjik)); fcikpc = (-dt1dik*at2)+(aaa2*dtsjik*dctik*(1.0-tspijl)); fcjlpc = (-dt1djl*at2)+(aaa2*dtsijl*dctjl*(1.0-tspjik)); fcjkpc = (-dt1djk*at2)+(aaa2*dtsjik*dctjk*(1.0-tspijl)); fcilpc = (-dt1dil*at2)+(aaa2*dtsijl*dctil*(1.0-tspjik)); F23[0] = (fcijpc*r23[0])+(aa*dt2dij[0]); F23[1] = (fcijpc*r23[1])+(aa*dt2dij[1]); F23[2] = (fcijpc*r23[2])+(aa*dt2dij[2]); F12[0] = (fcikpc*r21[0])+(aa*dt2dik[0]); F12[1] = (fcikpc*r21[1])+(aa*dt2dik[1]); F12[2] = (fcikpc*r21[2])+(aa*dt2dik[2]); F34[0] = (fcjlpc*r34[0])+(aa*dt2djl[0]); F34[1] = (fcjlpc*r34[1])+(aa*dt2djl[1]); F34[2] = (fcjlpc*r34[2])+(aa*dt2djl[2]); F31[0] = (fcjkpc*rjk[0]); F31[1] = (fcjkpc*rjk[1]); F31[2] = (fcjkpc*rjk[2]); F24[0] = (fcilpc*ril[0]); F24[1] = (fcilpc*ril[1]); F24[2] = (fcilpc*ril[2]); f1[0] = -F12[0]-F31[0]; f1[1] = -F12[1]-F31[1]; f1[2] = -F12[2]-F31[2]; f2[0] = F23[0]+F12[0]+F24[0]; f2[1] = F23[1]+F12[1]+F24[1]; f2[2] = F23[2]+F12[2]+F24[2]; f3[0] = -F23[0]+F34[0]+F31[0]; f3[1] = -F23[1]+F34[1]+F31[1]; f3[2] = -F23[2]+F34[2]+F31[2]; f4[0] = -F34[0]-F24[0]; f4[1] = -F34[1]-F24[1]; f4[2] = -F34[2]-F24[2]; // coordination forces tmp2 = VA*Tij*((1.0-(om1234*om1234))) * (1.0-tspjik)*(1.0-tspijl)*dw21*w34/r21mag; f2[0] -= tmp2*r21[0]; f2[1] -= tmp2*r21[1]; f2[2] -= tmp2*r21[2]; f1[0] += tmp2*r21[0]; f1[1] += tmp2*r21[1]; f1[2] += tmp2*r21[2]; tmp2 = VA*Tij*((1.0-(om1234*om1234))) * (1.0-tspjik)*(1.0-tspijl)*w21*dw34/r34mag; f3[0] -= tmp2*r34[0]; f3[1] -= tmp2*r34[1]; f3[2] -= tmp2*r34[2]; f4[0] += tmp2*r34[0]; f4[1] += tmp2*r34[1]; f4[2] += tmp2*r34[2]; f[atom1][0] += f1[0]; f[atom1][1] += f1[1]; f[atom1][2] += f1[2]; f[atom2][0] += f2[0]; f[atom2][1] += f2[1]; f[atom2][2] += f2[2]; f[atom3][0] += f3[0]; f[atom3][1] += f3[1]; f[atom3][2] += f3[2]; f[atom4][0] += f4[0]; f[atom4][1] += f4[1]; f[atom4][2] += f4[2]; if (vflag_atom) { r13[0] = -rjk[0]; r13[1] = -rjk[1]; r13[2] = -rjk[2]; r43[0] = -r34[0]; r43[1] = -r34[1]; r43[2] = -r34[2]; v_tally4(atom1,atom2,atom3,atom4,f1,f2,f4,r13,r23,r43); } } } } } } } REBO_neighs = REBO_firstneigh[i]; for (k = 0; k < REBO_numneigh[i]; k++) { atomk = REBO_neighs[k]; if (atomk != atomj) { ktype = map[type[atomk]]; rik[0] = x[atomi][0]-x[atomk][0]; rik[1] = x[atomi][1]-x[atomk][1]; rik[2] = x[atomi][2]-x[atomk][2]; rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2])); wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik); Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] - (wik*kronecker(itype,1)); SpN = Sp(Nki,Nmin,Nmax,dNki); tmp2 = VA*dN3[0]*dwik*Etmp/rikmag; f[atomi][0] -= tmp2*rik[0]; f[atomi][1] -= tmp2*rik[1]; f[atomi][2] -= tmp2*rik[2]; f[atomk][0] += tmp2*rik[0]; f[atomk][1] += tmp2*rik[1]; f[atomk][2] += tmp2*rik[2]; if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik); tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)*Etmp/rikmag; f[atomi][0] -= tmp2*rik[0]; f[atomi][1] -= tmp2*rik[1]; f[atomi][2] -= tmp2*rik[2]; f[atomk][0] += tmp2*rik[0]; f[atomk][1] += tmp2*rik[1]; f[atomk][2] += tmp2*rik[2]; if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik); if (fabs(dNki) > TOL) { REBO_neighs_k = REBO_firstneigh[atomk]; for (n = 0; n < REBO_numneigh[atomk]; n++) { atomn = REBO_neighs_k[n]; ntype = map[type[atomn]]; if (atomn !=atomi) { rkn[0] = x[atomk][0]-x[atomn][0]; rkn[1] = x[atomk][1]-x[atomn][1]; rkn[2] = x[atomk][2]-x[atomn][2]; rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2])); Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn); tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)*Etmp/rknmag; f[atomk][0] -= tmp2*rkn[0]; f[atomk][1] -= tmp2*rkn[1]; f[atomk][2] -= tmp2*rkn[2]; f[atomn][0] += tmp2*rkn[0]; f[atomn][1] += tmp2*rkn[1]; f[atomn][2] += tmp2*rkn[2]; if (vflag_atom) v_tally2(atomk,atomn,-tmp2,rkn); } } } } } // Tij forces REBO_neighs = REBO_firstneigh[j]; for (l = 0; l < REBO_numneigh[j]; l++) { atoml = REBO_neighs[l]; if (atoml != atomi) { ltype = map[type[atoml]]; rjl[0] = x[atomj][0]-x[atoml][0]; rjl[1] = x[atomj][1]-x[atoml][1]; rjl[2] = x[atomj][2]-x[atoml][2]; rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2])); wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl); Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] - (wjl*kronecker(jtype,1)); SpN = Sp(Nlj,Nmin,Nmax,dNlj); tmp2 = VA*dN3[1]*dwjl*Etmp/rjlmag; f[atomj][0] -= tmp2*rjl[0]; f[atomj][1] -= tmp2*rjl[1]; f[atomj][2] -= tmp2*rjl[2]; f[atoml][0] += tmp2*rjl[0]; f[atoml][1] += tmp2*rjl[1]; f[atoml][2] += tmp2*rjl[2]; if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl); tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)*Etmp/rjlmag; f[atomj][0] -= tmp2*rjl[0]; f[atomj][1] -= tmp2*rjl[1]; f[atomj][2] -= tmp2*rjl[2]; f[atoml][0] += tmp2*rjl[0]; f[atoml][1] += tmp2*rjl[1]; f[atoml][2] += tmp2*rjl[2]; if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl); if (fabs(dNlj) > TOL) { REBO_neighs_l = REBO_firstneigh[atoml]; for (n = 0; n < REBO_numneigh[atoml]; n++) { atomn = REBO_neighs_l[n]; ntype = map[type[atomn]]; if (atomn != atomj) { rln[0] = x[atoml][0]-x[atomn][0]; rln[1] = x[atoml][1]-x[atomn][1]; rln[2] = x[atoml][2]-x[atomn][2]; rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2])); Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln); tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)*Etmp/rlnmag; f[atoml][0] -= tmp2*rln[0]; f[atoml][1] -= tmp2*rln[1]; f[atoml][2] -= tmp2*rln[2]; f[atomn][0] += tmp2*rln[0]; f[atomn][1] += tmp2*rln[1]; f[atomn][2] += tmp2*rln[2]; if (vflag_atom) v_tally2(atoml,atomn,-tmp2,rln); } } } } } } } return Stb; } /* ---------------------------------------------------------------------- G spline ------------------------------------------------------------------------- */ double PairAIREBO::gSpline(double costh, double Nij, int typei, double *dgdc, double *dgdN) { double coeffs[6],dS,g1,g2,dg1,dg2,cut,g; int i,j; i = 0; j = 0; g = 0.0; cut = 0.0; dS = 0.0; dg1 = 0.0; dg2 = 0.0; *dgdc = 0.0; *dgdN = 0.0; // central atom is Carbon if (typei == 0) { if (costh < gCdom[0]) costh = gCdom[0]; if (costh > gCdom[4]) costh = gCdom[4]; if (Nij >= NCmax) { for (i = 0; i < 4; i++) { if (costh >= gCdom[i] && costh <= gCdom[i+1]) { for (j = 0; j < 6; j++) coeffs[j] = gC2[i][j]; } } g2 = Sp5th(costh,coeffs,&dg2); g = g2; *dgdc = dg2; *dgdN = 0.0; } if (Nij <= NCmin) { for (i = 0; i < 4; i++) { if (costh >= gCdom[i] && costh <= gCdom[i+1]) { for (j = 0; j < 6; j++) coeffs[j] = gC1[i][j]; } } g1 = Sp5th(costh,coeffs,&dg1); g = g1; *dgdc = dg1; *dgdN = 0.0; } if (Nij > NCmin && Nij < NCmax) { for (i = 0; i < 4; i++) { if (costh >= gCdom[i] && costh <= gCdom[i+1]) { for (j = 0; j < 6; j++) coeffs[j] = gC1[i][j]; } } g1 = Sp5th(costh,coeffs,&dg1); for (i = 0; i < 4; i++) { if (costh >= gCdom[i] && costh <= gCdom[i+1]) { for (j = 0; j < 6; j++) coeffs[j] = gC2[i][j]; } } g2 = Sp5th(costh,coeffs,&dg2); cut = Sp(Nij,NCmin,NCmax,dS); g = g2+cut*(g1-g2); *dgdc = dg2+(cut*(dg1-dg2)); *dgdN = dS*(g1-g2); } } // central atom is Hydrogen if (typei == 1) { if (costh < gHdom[0]) costh = gHdom[0]; if (costh > gHdom[3]) costh = gHdom[3]; for (i = 0; i < 3; i++) { if (costh >= gHdom[i] && costh <= gHdom[i+1]) { for (j = 0; j < 6; j++) coeffs[j] = gH[i][j]; } } g = Sp5th(costh,coeffs,&dg1); *dgdN = 0.0; *dgdc = dg1; } return g; } /* ---------------------------------------------------------------------- Pij spline ------------------------------------------------------------------------- */ double PairAIREBO::PijSpline(double NijC, double NijH, int typei, int typej, double dN2[2]) { int x,y,i,done; double Pij,coeffs[16]; for (i = 0; i < 16; i++) coeffs[i]=0.0; x = 0; y = 0; dN2[0] = 0.0; dN2[1] = 0.0; done = 0; // if inputs are out of bounds set them back to a point in bounds if (typei == 0 && typej == 0) { if (NijC < pCCdom[0][0]) NijC=pCCdom[0][0]; if (NijC > pCCdom[0][1]) NijC=pCCdom[0][1]; if (NijH < pCCdom[1][0]) NijH=pCCdom[1][0]; if (NijH > pCCdom[1][1]) NijH=pCCdom[1][1]; if (fabs(NijC-floor(NijC)) < TOL && fabs(NijH-floor(NijH)) < TOL) { Pij = PCCf[(int) NijC][(int) NijH]; dN2[0] = PCCdfdx[(int) NijC][(int) NijH]; dN2[1] = PCCdfdy[(int) NijC][(int) NijH]; done = 1; } if (done == 0) { x = (int) (floor(NijC)); y = (int) (floor(NijH)); for (i = 0; i<16; i++) coeffs[i] = pCC[x][y][i]; Pij = Spbicubic(NijC,NijH,coeffs,dN2); } } // if inputs are out of bounds set them back to a point in bounds if (typei == 0 && typej == 1){ if (NijC < pCHdom[0][0]) NijC=pCHdom[0][0]; if (NijC > pCHdom[0][1]) NijC=pCHdom[0][1]; if (NijH < pCHdom[1][0]) NijH=pCHdom[1][0]; if (NijH > pCHdom[1][1]) NijH=pCHdom[1][1]; if (fabs(NijC-floor(NijC)) < TOL && fabs(NijH-floor(NijH)) < TOL) { Pij = PCHf[(int) NijC][(int) NijH]; dN2[0] = PCHdfdx[(int) NijC][(int) NijH]; dN2[1] = PCHdfdy[(int) NijC][(int) NijH]; done = 1; } if (done == 0) { x = (int) (floor(NijC)); y = (int) (floor(NijH)); for (i = 0; i<16; i++) coeffs[i] = pCH[x][y][i]; Pij = Spbicubic(NijC,NijH,coeffs,dN2); } } if (typei == 1 && typej == 0) { Pij = 0.0; dN2[0] = 0.0; dN2[1] = 0.0; } if (typei == 1 && typej == 1) { Pij = 0.0; dN2[0] = 0.0; dN2[1] = 0.0; } return Pij; } /* ---------------------------------------------------------------------- PiRC spline ------------------------------------------------------------------------- */ double PairAIREBO::piRCSpline(double Nij, double Nji, double Nijconj, int typei, int typej, double dN3[3]) { int x,y,z,i,done; double piRC,coeffs[64]; x=0; y=0; z=0; i=0; done=0; for (i=0; i<64; i++) coeffs[i]=0.0; if (typei==0 && typej==0) { //if the inputs are out of bounds set them back to a point in bounds if (NijpiCCdom[0][1]) Nij=piCCdom[0][1]; if (NjipiCCdom[1][1]) Nji=piCCdom[1][1]; if (NijconjpiCCdom[2][1]) Nijconj=piCCdom[2][1]; if (fabs(Nij-floor(Nij))=(double) i && Nij<=(double) i+1) x=i; for (i=0; i=(double) i && Nji<=(double) i+1) y=i; for (i=0; i=(double) i && Nijconj<=(double) i+1) z=i; for (i=0; i<64; i++) coeffs[i]=piCC[x][y][z][i]; piRC=Sptricubic(Nij,Nji,Nijconj,coeffs,dN3); } } // CH interaction if ((typei==0 && typej==1) || (typei==1 && typej==0)) { // if the inputs are out of bounds set them back to a point in bounds if (NijpiCHdom[0][1] || NjipiCHdom[1][1] || NijconjpiCHdom[2][1]) { if (NijpiCHdom[0][1]) Nij=piCHdom[0][1]; if (NjipiCHdom[1][1]) Nji=piCHdom[1][1]; if (NijconjpiCHdom[2][1]) Nijconj=piCHdom[2][1]; } if (fabs(Nij-floor(Nij))=i && Nij<=i+1) x=i; for (i=0; i=i && Nji<=i+1) y=i; for (i=0; i=i && Nijconj<=i+1) z=i; for (i=0; i<64; i++) coeffs[i]=piCH[x][y][z][i]; piRC=Sptricubic(Nij,Nji,Nijconj,coeffs,dN3); } } if (typei==1 && typej==1) { if (NijpiHHdom[0][1] || NjipiHHdom[1][1] || NijconjpiHHdom[2][1]) { Nij=0.0; Nji=0.0; Nijconj=0.0; } if (fabs(Nij-floor(Nij))=i && Nij<=i+1) x=i; for (i=0; i=i && Nji<=i+1) y=i; for (i=0; i=i && Nijconj<=i+1) z=i; for (i=0; i<64; i++) coeffs[i]=piHH[x][y][z][i]; piRC=Sptricubic(Nij,Nji,Nijconj,coeffs,dN3); } } return piRC; } /* ---------------------------------------------------------------------- Tij spline ------------------------------------------------------------------------- */ double PairAIREBO::TijSpline(double Nij, double Nji, double Nijconj, double dN3[3]) { int x,y,z,i,done; double Tijf,coeffs[64]; x=0; y=0; z=0; i=0; Tijf=0.0; done=0; for (i=0; i<64; i++) coeffs[i]=0.0; //if the inputs are out of bounds set them back to a point in bounds if (NijTijdom[0][1]) Nij=Tijdom[0][1]; if (NjiTijdom[1][1]) Nji=Tijdom[1][1]; if (NijconjTijdom[2][1]) Nijconj=Tijdom[2][1]; if (fabs(Nij-floor(Nij))=i && Nij<=i+1) x=i; for (i=0; i=i && Nji<=i+1) y=i; for (i=0; i=i && Nijconj<=i+1) z=i; for (i=0; i<64; i++) coeffs[i]=Tijc[x][y][z][i]; Tijf=Sptricubic(Nij,Nji,Nijconj,coeffs,dN3); } return Tijf; } /* ---------------------------------------------------------------------- read AIREBO potential file ------------------------------------------------------------------------- */ void PairAIREBO::read_file(char *filename) { int i,j,k,l,limit; char s[MAXLINE]; // REBO Parameters (AIREBO) double rcmin_CC,rcmin_CH,rcmin_HH,rcmax_CC,rcmax_CH, rcmax_HH,rcmaxp_CC,rcmaxp_CH,rcmaxp_HH; double Q_CC,Q_CH,Q_HH,alpha_CC,alpha_CH,alpha_HH,A_CC,A_CH,A_HH; double BIJc_CC1,BIJc_CC2,BIJc_CC3,BIJc_CH1,BIJc_CH2,BIJc_CH3, BIJc_HH1,BIJc_HH2,BIJc_HH3; double Beta_CC1,Beta_CC2,Beta_CC3,Beta_CH1,Beta_CH2,Beta_CH3, Beta_HH1,Beta_HH2,Beta_HH3; double rho_CC,rho_CH,rho_HH; // LJ Parameters (AIREBO) double rcLJmin_CC,rcLJmin_CH,rcLJmin_HH,rcLJmax_CC,rcLJmax_CH, rcLJmax_HH,bLJmin_CC; double bLJmin_CH,bLJmin_HH,bLJmax_CC,bLJmax_CH,bLJmax_HH, epsilon_CC,epsilon_CH,epsilon_HH; double sigma_CC,sigma_CH,sigma_HH,epsilonT_CCCC,epsilonT_CCCH,epsilonT_HCCH; // additional parameters for Morse potential. double epsilonM_CC,epsilonM_CH,epsilonM_HH,alphaM_CC,alphaM_CH,alphaM_HH; double reqM_CC,reqM_CH,reqM_HH; MPI_Comm_rank(world,&me); // read file on proc 0 if (me == 0) { FILE *fp = force->open_potential(filename); if (fp == NULL) { char str[128]; if (morseflag) sprintf(str,"Cannot open AIREBO-M potential file %s",filename); else sprintf(str,"Cannot open AIREBO potential file %s",filename); error->one(FLERR,str); } // skip initial comment lines while (1) { fgets(s,MAXLINE,fp); if (s[0] != '#') break; } // read parameters fgets(s,MAXLINE,fp); sscanf(s,"%lg",&rcmin_CC); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&rcmin_CH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&rcmin_HH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&rcmax_CC); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&rcmax_CH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&rcmax_HH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&rcmaxp_CC); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&rcmaxp_CH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&rcmaxp_HH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&smin); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&Nmin); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&Nmax); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&NCmin); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&NCmax); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&Q_CC); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&Q_CH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&Q_HH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&alpha_CC); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&alpha_CH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&alpha_HH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&A_CC); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&A_CH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&A_HH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&BIJc_CC1); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&BIJc_CC2); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&BIJc_CC3); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&BIJc_CH1); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&BIJc_CH2); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&BIJc_CH3); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&BIJc_HH1); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&BIJc_HH2); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&BIJc_HH3); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&Beta_CC1); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&Beta_CC2); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&Beta_CC3); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&Beta_CH1); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&Beta_CH2); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&Beta_CH3); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&Beta_HH1); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&Beta_HH2); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&Beta_HH3); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&rho_CC); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&rho_CH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&rho_HH); // LJ parameters fgets(s,MAXLINE,fp); sscanf(s,"%lg",&rcLJmin_CC); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&rcLJmin_CH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&rcLJmin_HH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&rcLJmax_CC); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&rcLJmax_CH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&rcLJmax_HH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&bLJmin_CC); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&bLJmin_CH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&bLJmin_HH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&bLJmax_CC); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&bLJmax_CH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&bLJmax_HH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&epsilon_CC); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&epsilon_CH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&epsilon_HH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&sigma_CC); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&sigma_CH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&sigma_HH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&epsilonT_CCCC); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&epsilonT_CCCH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&epsilonT_HCCH); if (morseflag) { // lines for reading in MORSE parameters from CH.airebo_m file fgets(s,MAXLINE,fp); sscanf(s,"%lg",&epsilonM_CC); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&epsilonM_CH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&epsilonM_HH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&alphaM_CC); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&alphaM_CH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&alphaM_HH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&reqM_CC); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&reqM_CH); fgets(s,MAXLINE,fp); sscanf(s,"%lg",&reqM_HH); } // gC spline fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); // number-1 = # of domains for the spline fgets(s,MAXLINE,fp); sscanf(s,"%d",&limit); for (i = 0; i < limit; i++) { fgets(s,MAXLINE,fp); sscanf(s,"%lg",&gCdom[i]); } fgets(s,MAXLINE,fp); for (i = 0; i < limit-1; i++) { for (j = 0; j < 6; j++) { fgets(s,MAXLINE,fp); sscanf(s,"%lg",&gC1[i][j]); } } fgets(s,MAXLINE,fp); for (i = 0; i < limit-1; i++) { for (j = 0; j < 6; j++) { fgets(s,MAXLINE,fp); sscanf(s,"%lg",&gC2[i][j]); } } // gH spline fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); sscanf(s,"%d",&limit); for (i = 0; i < limit; i++) { fgets(s,MAXLINE,fp); sscanf(s,"%lg",&gHdom[i]); } fgets(s,MAXLINE,fp); for (i = 0; i < limit-1; i++) { for (j = 0; j < 6; j++) { fgets(s,MAXLINE,fp); sscanf(s,"%lg",&gH[i][j]); } } // pCC spline fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); sscanf(s,"%d",&limit); for (i = 0; i < limit/2; i++) { for (j = 0; j < limit/2; j++) { fgets(s,MAXLINE,fp); sscanf(s,"%lg",&pCCdom[i][j]); } } fgets(s,MAXLINE,fp); for (i = 0; i < (int) pCCdom[0][1]; i++) { for (j = 0; j < (int) pCCdom[1][1]; j++) { for (k = 0; k < 16; k++) { fgets(s,MAXLINE,fp); sscanf(s,"%lg",&pCC[i][j][k]); } } } // pCH spline fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); sscanf(s,"%d",&limit); for (i = 0; i < limit/2; i++) { for (j = 0; j < limit/2; j++) { fgets(s,MAXLINE,fp); sscanf(s,"%lg",&pCHdom[i][j]); } } fgets(s,MAXLINE,fp); for (i = 0; i < (int) pCHdom[0][1]; i++) { for (j = 0; j < (int) pCHdom[1][1]; j++) { for (k = 0; k < 16; k++) { fgets(s,MAXLINE,fp); sscanf(s,"%lg",&pCH[i][j][k]); } } } // piCC cpline fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); sscanf(s,"%d",&limit); for (i = 0; i < limit/2; i++) { for (j = 0; j < limit/3; j++) { fgets(s,MAXLINE,fp); sscanf(s,"%lg",&piCCdom[i][j]); } } fgets(s,MAXLINE,fp); for (i = 0; i < (int) piCCdom[0][1]; i++) { for (j = 0; j < (int) piCCdom[1][1]; j++) { for (k = 0; k < (int) piCCdom[2][1]; k++) { for (l = 0; l < 64; l = l+1) { fgets(s,MAXLINE,fp); sscanf(s,"%lg",&piCC[i][j][k][l]); } } } } // piCH spline fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); sscanf(s,"%d",&limit); for (i = 0; i < limit/2; i++) { for (j = 0; j < limit/3; j++) { fgets(s,MAXLINE,fp); sscanf(s,"%lg",&piCHdom[i][j]); } } fgets(s,MAXLINE,fp); for (i = 0; i < (int) piCHdom[0][1]; i++) { for (j = 0; j < (int) piCHdom[1][1]; j++) { for (k = 0; k < (int) piCHdom[2][1]; k++) { for (l = 0; l < 64; l = l+1) { fgets(s,MAXLINE,fp); sscanf(s,"%lg",&piCH[i][j][k][l]); } } } } // piHH spline fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); sscanf(s,"%d",&limit); for (i = 0; i < limit/2; i++) { for (j = 0; j < limit/3; j++) { fgets(s,MAXLINE,fp); sscanf(s,"%lg",&piHHdom[i][j]); } } fgets(s,MAXLINE,fp); for (i = 0; i < (int) piHHdom[0][1]; i++) { for (j = 0; j < (int) piHHdom[1][1]; j++) { for (k = 0; k < (int) piHHdom[2][1]; k++) { for (l = 0; l < 64; l = l+1) { fgets(s,MAXLINE,fp); sscanf(s,"%lg",&piHH[i][j][k][l]); } } } } // Tij spline fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); fgets(s,MAXLINE,fp); sscanf(s,"%d",&limit); for (i = 0; i < limit/2; i++) { for (j = 0; j < limit/3; j++) { fgets(s,MAXLINE,fp); sscanf(s,"%lg",&Tijdom[i][j]); } } fgets(s,MAXLINE,fp); for (i = 0; i < (int) Tijdom[0][1]; i++) { for (j = 0; j < (int) Tijdom[1][1]; j++) { for (k = 0; k < (int) Tijdom[2][1]; k++) { for (l = 0; l < 64; l = l+1) { fgets(s,MAXLINE,fp); sscanf(s,"%lg",&Tijc[i][j][k][l]); } } } } fclose(fp); } // store read-in values in arrays if (me == 0) { // REBO rcmin[0][0] = rcmin_CC; rcmin[0][1] = rcmin_CH; rcmin[1][0] = rcmin[0][1]; rcmin[1][1] = rcmin_HH; rcmax[0][0] = rcmax_CC; rcmax[0][1] = rcmax_CH; rcmax[1][0] = rcmax[0][1]; rcmax[1][1] = rcmax_HH; rcmaxsq[0][0] = rcmax[0][0]*rcmax[0][0]; rcmaxsq[1][0] = rcmax[1][0]*rcmax[1][0]; rcmaxsq[0][1] = rcmax[0][1]*rcmax[0][1]; rcmaxsq[1][1] = rcmax[1][1]*rcmax[1][1]; rcmaxp[0][0] = rcmaxp_CC; rcmaxp[0][1] = rcmaxp_CH; rcmaxp[1][0] = rcmaxp[0][1]; rcmaxp[1][1] = rcmaxp_HH; Q[0][0] = Q_CC; Q[0][1] = Q_CH; Q[1][0] = Q[0][1]; Q[1][1] = Q_HH; alpha[0][0] = alpha_CC; alpha[0][1] = alpha_CH; alpha[1][0] = alpha[0][1]; alpha[1][1] = alpha_HH; A[0][0] = A_CC; A[0][1] = A_CH; A[1][0] = A[0][1]; A[1][1] = A_HH; rho[0][0] = rho_CC; rho[0][1] = rho_CH; rho[1][0] = rho[0][1]; rho[1][1] = rho_HH; BIJc[0][0][0] = BIJc_CC1; BIJc[0][0][1] = BIJc_CC2; BIJc[0][0][2] = BIJc_CC3; BIJc[0][1][0] = BIJc_CH1; BIJc[0][1][1] = BIJc_CH2; BIJc[0][1][2] = BIJc_CH3; BIJc[1][0][0] = BIJc_CH1; BIJc[1][0][1] = BIJc_CH2; BIJc[1][0][2] = BIJc_CH3; BIJc[1][1][0] = BIJc_HH1; BIJc[1][1][1] = BIJc_HH2; BIJc[1][1][2] = BIJc_HH3; Beta[0][0][0] = Beta_CC1; Beta[0][0][1] = Beta_CC2; Beta[0][0][2] = Beta_CC3; Beta[0][1][0] = Beta_CH1; Beta[0][1][1] = Beta_CH2; Beta[0][1][2] = Beta_CH3; Beta[1][0][0] = Beta_CH1; Beta[1][0][1] = Beta_CH2; Beta[1][0][2] = Beta_CH3; Beta[1][1][0] = Beta_HH1; Beta[1][1][1] = Beta_HH2; Beta[1][1][2] = Beta_HH3; // LJ rcLJmin[0][0] = rcLJmin_CC; rcLJmin[0][1] = rcLJmin_CH; rcLJmin[1][0] = rcLJmin[0][1]; rcLJmin[1][1] = rcLJmin_HH; rcLJmax[0][0] = rcLJmax_CC; rcLJmax[0][1] = rcLJmax_CH; rcLJmax[1][0] = rcLJmax[0][1]; rcLJmax[1][1] = rcLJmax_HH; rcLJmaxsq[0][0] = rcLJmax[0][0]*rcLJmax[0][0]; rcLJmaxsq[1][0] = rcLJmax[1][0]*rcLJmax[1][0]; rcLJmaxsq[0][1] = rcLJmax[0][1]*rcLJmax[0][1]; rcLJmaxsq[1][1] = rcLJmax[1][1]*rcLJmax[1][1]; bLJmin[0][0] = bLJmin_CC; bLJmin[0][1] = bLJmin_CH; bLJmin[1][0] = bLJmin[0][1]; bLJmin[1][1] = bLJmin_HH; bLJmax[0][0] = bLJmax_CC; bLJmax[0][1] = bLJmax_CH; bLJmax[1][0] = bLJmax[0][1]; bLJmax[1][1] = bLJmax_HH; epsilon[0][0] = epsilon_CC; epsilon[0][1] = epsilon_CH; epsilon[1][0] = epsilon[0][1]; epsilon[1][1] = epsilon_HH; sigma[0][0] = sigma_CC; sigma[0][1] = sigma_CH; sigma[1][0] = sigma[0][1]; sigma[1][1] = sigma_HH; if (morseflag) { // Morse parameter assignments epsilonM[0][0] = epsilonM_CC; epsilonM[0][1] = epsilonM_CH; epsilonM[1][0] = epsilonM[0][1]; epsilonM[1][1] = epsilonM_HH; alphaM[0][0] = alphaM_CC; alphaM[0][1] = alphaM_CH; alphaM[1][0] = alphaM[0][1]; alphaM[1][1] = alphaM_HH; reqM[0][0] = reqM_CC; reqM[0][1] = reqM_CH; reqM[1][0] = reqM[0][1]; reqM[1][1] = reqM_HH; } // torsional thmin = -1.0; thmax = -0.995; epsilonT[0][0] = epsilonT_CCCC; epsilonT[0][1] = epsilonT_CCCH; epsilonT[1][0] = epsilonT[0][1]; epsilonT[1][1] = epsilonT_HCCH; } // broadcast read-in and setup values MPI_Bcast(&thmin,1,MPI_DOUBLE,0,world); MPI_Bcast(&thmax,1,MPI_DOUBLE,0,world); MPI_Bcast(&smin,1,MPI_DOUBLE,0,world); MPI_Bcast(&Nmin,1,MPI_DOUBLE,0,world); MPI_Bcast(&Nmax,1,MPI_DOUBLE,0,world); MPI_Bcast(&NCmin,1,MPI_DOUBLE,0,world); MPI_Bcast(&NCmax,1,MPI_DOUBLE,0,world); MPI_Bcast(&rcmin[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&rcmax[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&rcmaxsq[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&rcmaxp[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&Q[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&alpha[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&A[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&rho[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&BIJc[0][0][0],12,MPI_DOUBLE,0,world); MPI_Bcast(&Beta[0][0][0],12,MPI_DOUBLE,0,world); MPI_Bcast(&rcLJmin[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&rcLJmax[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&rcLJmaxsq[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&rcLJmin[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&rcLJmin[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&rcLJmin[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&rcLJmax[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&bLJmin[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&bLJmax[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&epsilon[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&sigma[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&epsilonT[0][0],4,MPI_DOUBLE,0,world); if (morseflag) { // Morse parameter broadcast MPI_Bcast(&epsilonM[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&alphaM[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&reqM[0][0],4,MPI_DOUBLE,0,world); } MPI_Bcast(&gCdom[0],5,MPI_DOUBLE,0,world); MPI_Bcast(&gC1[0][0],24,MPI_DOUBLE,0,world); MPI_Bcast(&gC2[0][0],24,MPI_DOUBLE,0,world); MPI_Bcast(&gHdom[0],4,MPI_DOUBLE,0,world); MPI_Bcast(&gH[0][0],18,MPI_DOUBLE,0,world); MPI_Bcast(&pCCdom[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&pCHdom[0][0],4,MPI_DOUBLE,0,world); MPI_Bcast(&pCC[0][0][0],256,MPI_DOUBLE,0,world); MPI_Bcast(&pCH[0][0][0],256,MPI_DOUBLE,0,world); MPI_Bcast(&piCCdom[0][0],6,MPI_DOUBLE,0,world); MPI_Bcast(&piCHdom[0][0],6,MPI_DOUBLE,0,world); MPI_Bcast(&piHHdom[0][0],6,MPI_DOUBLE,0,world); MPI_Bcast(&piCC[0][0][0][0],9216,MPI_DOUBLE,0,world); MPI_Bcast(&piCH[0][0][0][0],9216,MPI_DOUBLE,0,world); MPI_Bcast(&piHH[0][0][0][0],9216,MPI_DOUBLE,0,world); MPI_Bcast(&Tijdom[0][0],6,MPI_DOUBLE,0,world); MPI_Bcast(&Tijc[0][0][0][0],9216,MPI_DOUBLE,0,world); } // ---------------------------------------------------------------------- // generic Spline functions // ---------------------------------------------------------------------- /* ---------------------------------------------------------------------- fifth order spline evaluation ------------------------------------------------------------------------- */ double PairAIREBO::Sp5th(double x, double coeffs[6], double *df) { double f, d; const double x2 = x*x; const double x3 = x2*x; f = coeffs[0]; f += coeffs[1]*x; d = coeffs[1]; f += coeffs[2]*x2; d += 2.0*coeffs[2]*x; f += coeffs[3]*x3; d += 3.0*coeffs[3]*x2; f += coeffs[4]*x2*x2; d += 4.0*coeffs[4]*x3; f += coeffs[5]*x2*x3; d += 5.0*coeffs[5]*x2*x2; *df = d; return f; } /* ---------------------------------------------------------------------- bicubic spline evaluation ------------------------------------------------------------------------- */ double PairAIREBO::Spbicubic(double x, double y, double coeffs[16], double df[2]) { double f,xn,yn,xn1,yn1,c; int i,j; f = 0.0; df[0] = 0.0; df[1] = 0.0; xn = 1.0; for (i = 0; i < 4; i++) { yn = 1.0; for (j = 0; j < 4; j++) { c = coeffs[i*4+j]; f += c*xn*yn; if (i > 0) df[0] += c * ((double) i) * xn1 * yn; if (j > 0) df[1] += c * ((double) j) * xn * yn1; yn1 = yn; yn *= y; } xn1 = xn; xn *= x; } return f; } /* ---------------------------------------------------------------------- tricubic spline evaluation ------------------------------------------------------------------------- */ double PairAIREBO::Sptricubic(double x, double y, double z, double coeffs[64], double df[3]) { double f,ir,jr,kr,xn,yn,zn,xn1,yn1,zn1,c; int i,j,k; f = 0.0; df[0] = 0.0; df[1] = 0.0; df[2] = 0.0; xn = 1.0; for (i = 0; i < 4; i++) { ir = (double) i; yn = 1.0; for (j = 0; j < 4; j++) { jr = (double) j; zn = 1.0; for (k = 0; k < 4; k++) { kr = (double) k; c = coeffs[16*i+4*j+k]; f += c*xn*yn*zn; if (i > 0) df[0] += c * ir * xn1 * yn * zn; if (j > 0) df[1] += c * jr * xn * yn1 * zn; if (k > 0) df[2] += c * kr * xn * yn * zn1; zn1 = zn; zn *= z; } yn1 = yn; yn *= y; } xn1 = xn; xn *= x; } return f; } /* ---------------------------------------------------------------------- initialize spline knot values ------------------------------------------------------------------------- */ void PairAIREBO::spline_init() { int i,j,k; for (i = 0; i < 5; i++) { for (j = 0; j < 5; j++) { PCCf[i][j] = 0.0; PCCdfdx[i][j] = 0.0; PCCdfdy[i][j] = 0.0; PCHf[i][j] = 0.0; PCHdfdx[i][j] = 0.0; PCHdfdy[i][j] = 0.0; } } PCCf[0][2] = -0.00050; PCCf[0][3] = 0.0161253646; PCCf[1][1] = -0.010960; PCCf[1][2] = 0.00632624824; - PCCf[2][0] = -0.0276030; + + // this one parameter for C-C interactions is different in REBO vs AIREBO + // see Favata, Micheletti, Ryu, Pugno, Comp Phys Comm (2016) + + PCCf[2][0] = PCCf_2_0; + PCCf[2][1] = 0.00317953083; PCHf[0][1] = 0.209336733; PCHf[0][2] = -0.0644496154; PCHf[0][3] = -0.303927546; PCHf[1][0] = 0.010; PCHf[1][1] = -0.125123401; PCHf[1][2] = -0.298905246; PCHf[2][0] = -0.122042146; PCHf[2][1] = -0.300529172; PCHf[3][0] = -0.307584705; for (i = 0; i < 5; i++) { for (j = 0; j < 5; j++) { for (k = 0; k < 10; k++) { piCCf[i][j][k] = 0.0; piCCdfdx[i][j][k] = 0.0; piCCdfdy[i][j][k] = 0.0; piCCdfdz[i][j][k] = 0.0; piCHf[i][j][k] = 0.0; piCHdfdx[i][j][k] = 0.0; piCHdfdy[i][j][k] = 0.0; piCHdfdz[i][j][k] = 0.0; piHHf[i][j][k] = 0.0; piHHdfdx[i][j][k] = 0.0; piHHdfdy[i][j][k] = 0.0; piHHdfdz[i][j][k] = 0.0; Tf[i][j][k] = 0.0; Tdfdx[i][j][k] = 0.0; Tdfdy[i][j][k] = 0.0; Tdfdz[i][j][k] = 0.0; } } } for (i = 3; i < 10; i++) piCCf[0][0][i] = 0.0049586079; piCCf[1][0][1] = 0.021693495; piCCf[0][1][1] = 0.021693495; for (i = 2; i < 10; i++) piCCf[1][0][i] = 0.0049586079; for (i = 2; i < 10; i++) piCCf[0][1][i] = 0.0049586079; piCCf[1][1][1] = 0.05250; piCCf[1][1][2] = -0.002088750; for (i = 3; i < 10; i++) piCCf[1][1][i] = -0.00804280; piCCf[2][0][1] = 0.024698831850; piCCf[0][2][1] = 0.024698831850; piCCf[2][0][2] = -0.00597133450; piCCf[0][2][2] = -0.00597133450; for (i = 3; i < 10; i++) piCCf[2][0][i] = 0.0049586079; for (i = 3; i < 10; i++) piCCf[0][2][i] = 0.0049586079; piCCf[2][1][1] = 0.00482478490; piCCf[1][2][1] = 0.00482478490; piCCf[2][1][2] = 0.0150; piCCf[1][2][2] = 0.0150; piCCf[2][1][3] = -0.010; piCCf[1][2][3] = -0.010; piCCf[2][1][4] = -0.01168893870; piCCf[1][2][4] = -0.01168893870; piCCf[2][1][5] = -0.013377877400; piCCf[1][2][5] = -0.013377877400; piCCf[2][1][6] = -0.015066816000; piCCf[1][2][6] = -0.015066816000; for (i = 7; i < 10; i++) piCCf[2][1][i] = -0.015066816000; for (i = 7; i < 10; i++) piCCf[1][2][i] = -0.015066816000; piCCf[2][2][1] = 0.0472247850; piCCf[2][2][2] = 0.0110; piCCf[2][2][3] = 0.0198529350; piCCf[2][2][4] = 0.01654411250; piCCf[2][2][5] = 0.013235290; piCCf[2][2][6] = 0.00992646749999 ; piCCf[2][2][7] = 0.006617644999; piCCf[2][2][8] = 0.00330882250; piCCf[3][0][1] = -0.05989946750; piCCf[0][3][1] = -0.05989946750; piCCf[3][0][2] = -0.05989946750; piCCf[0][3][2] = -0.05989946750; for (i = 3; i < 10; i++) piCCf[3][0][i] = 0.0049586079; for (i = 3; i < 10; i++) piCCf[0][3][i] = 0.0049586079; piCCf[3][1][2] = -0.0624183760; piCCf[1][3][2] = -0.0624183760; for (i = 3; i < 10; i++) piCCf[3][1][i] = -0.0624183760; for (i = 3; i < 10; i++) piCCf[1][3][i] = -0.0624183760; piCCf[3][2][1] = -0.02235469150; piCCf[2][3][1] = -0.02235469150; for (i = 2; i < 10; i++) piCCf[3][2][i] = -0.02235469150; for (i = 2; i < 10; i++) piCCf[2][3][i] = -0.02235469150; piCCdfdx[2][1][1] = -0.026250; piCCdfdx[2][1][5] = -0.0271880; piCCdfdx[2][1][6] = -0.0271880; for (i = 7; i < 10; i++) piCCdfdx[2][1][i] = -0.0271880; piCCdfdx[1][3][2] = 0.0187723882; for (i = 2; i < 10; i++) piCCdfdx[2][3][i] = 0.031209; piCCdfdy[1][2][1] = -0.026250; piCCdfdy[1][2][5] = -0.0271880; piCCdfdy[1][2][6] = -0.0271880; for (i = 7; i < 10; i++) piCCdfdy[1][2][i] = -0.0271880; piCCdfdy[3][1][2] = 0.0187723882; for (i = 2; i < 10; i++) piCCdfdy[3][2][i] = 0.031209; piCCdfdz[1][1][2] = -0.0302715; piCCdfdz[2][1][4] = -0.0100220; piCCdfdz[1][2][4] = -0.0100220; piCCdfdz[2][1][5] = -0.0100220; piCCdfdz[1][2][5] = -0.0100220; for (i = 4; i < 9; i++) piCCdfdz[2][2][i] = -0.0033090; // make top end of piCC flat instead of zero i = 4; for (j = 0; j < 4; j++){ for (k = 1; k < 11; k++){ piCCf[i][j][k] = piCCf[i-1][j][k]; } } for (i = 0; i < 4; i++){ // also enforces some symmetry for (j = i+1; j < 5; j++){ for (k = 1; k < 11; k++){ piCCf[i][j][k] = piCCf[j][i][k]; } } } for (k = 1; k < 11; k++) piCCf[4][4][k] = piCCf[3][4][k]; k = 10; for (i = 0; i < 5; i++){ for (j = 0; j < 5; j++){ piCCf[i][j][k] = piCCf[i][j][k-1]; } } piCHf[1][1][1] = -0.050; piCHf[1][1][2] = -0.050; piCHf[1][1][3] = -0.30; for (i = 4; i < 10; i++) piCHf[1][1][i] = -0.050; for (i = 5; i < 10; i++) piCHf[2][0][i] = -0.004523893758064; for (i = 5; i < 10; i++) piCHf[0][2][i] = -0.004523893758064; piCHf[2][1][2] = -0.250; piCHf[1][2][2] = -0.250; piCHf[2][1][3] = -0.250; piCHf[1][2][3] = -0.250; piCHf[3][1][1] = -0.10; piCHf[1][3][1] = -0.10; piCHf[3][1][2] = -0.125; piCHf[1][3][2] = -0.125; piCHf[3][1][3] = -0.125; piCHf[1][3][3] = -0.125; for (i = 4; i < 10; i++) piCHf[3][1][i] = -0.10; for (i = 4; i < 10; i++) piCHf[1][3][i] = -0.10; // make top end of piCH flat instead of zero // also enforces some symmetry i = 4; for (j = 0; j < 4; j++){ for (k = 1; k < 11; k++){ piCHf[i][j][k] = piCHf[i-1][j][k]; } } for (i = 0; i < 4; i++){ for (j = i+1; j < 5; j++){ for (k = 1; k < 11; k++){ piCHf[i][j][k] = piCHf[j][i][k]; } } } for (k = 1; k < 11; k++) piCHf[4][4][k] = piCHf[3][4][k]; k = 10; for (i = 0; i < 5; i++){ for (j = 0; j < 5; j++){ piCHf[i][j][k] = piCHf[i][j][k-1]; } } piHHf[1][1][1] = 0.124915958; Tf[2][2][1] = -0.035140; for (i = 2; i < 10; i++) Tf[2][2][i] = -0.0040480; } /* ---------------------------------------------------------------------- memory usage of local atom-based arrays ------------------------------------------------------------------------- */ double PairAIREBO::memory_usage() { double bytes = 0.0; bytes += maxlocal * sizeof(int); bytes += maxlocal * sizeof(int *); for (int i = 0; i < comm->nthreads; i++) bytes += ipage[i].size(); bytes += 2*maxlocal * sizeof(double); return bytes; } diff --git a/src/MANYBODY/pair_airebo.h b/src/MANYBODY/pair_airebo.h index 06bf6da55..e927794ec 100644 --- a/src/MANYBODY/pair_airebo.h +++ b/src/MANYBODY/pair_airebo.h @@ -1,219 +1,221 @@ /* -*- 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. ------------------------------------------------------------------------- */ #ifdef PAIR_CLASS PairStyle(airebo,PairAIREBO) #else #ifndef LMP_PAIR_AIREBO_H #define LMP_PAIR_AIREBO_H #include "pair.h" #include "my_page.h" #include #include "math_const.h" namespace LAMMPS_NS { class PairAIREBO : public Pair { public: PairAIREBO(class LAMMPS *); virtual ~PairAIREBO(); virtual void compute(int, int); virtual void settings(int, char **); void coeff(int, char **); void init_style(); double init_one(int, int); double memory_usage(); protected: int *map; // 0 (C), 1 (H), or -1 (NULL) for each type int me; int ljflag,torflag; // 0/1 if LJ/Morse,torsion terms included int morseflag; // 1 if Morse instead of LJ for non-bonded double cutlj; // user-specified LJ cutoff double cutljrebosq; // cut for when to compute // REBO neighs of ghost atoms double **cutljsq; // LJ cutoffs for C,H types double **lj1,**lj2,**lj3,**lj4; // pre-computed LJ coeffs for C,H types double cut3rebo; // maximum distance for 3rd REBO neigh int maxlocal; // size of numneigh, firstneigh arrays int pgsize; // size of neighbor page int oneatom; // max # of neighbors for one atom MyPage *ipage; // neighbor list pages int *REBO_numneigh; // # of pair neighbors for each atom int **REBO_firstneigh; // ptr to 1st neighbor of each atom double *closestdistsq; // closest owned atom dist to each ghost double *nC,*nH; // sum of weighting fns with REBO neighs double smin,Nmin,Nmax,NCmin,NCmax,thmin,thmax; double rcmin[2][2],rcmax[2][2],rcmaxsq[2][2],rcmaxp[2][2]; double Q[2][2],alpha[2][2],A[2][2],rho[2][2],BIJc[2][2][3],Beta[2][2][3]; double rcLJmin[2][2],rcLJmax[2][2],rcLJmaxsq[2][2],bLJmin[2][2],bLJmax[2][2]; double epsilon[2][2],sigma[2][2],epsilonT[2][2]; // parameters for Morse variant + double epsilonM[2][2],alphaM[2][2],reqM[2][2]; // spline coefficients double gCdom[5],gC1[4][6],gC2[4][6],gHdom[4],gH[3][6]; double pCCdom[2][2],pCHdom[2][2],pCC[4][4][16],pCH[4][4][16]; double piCCdom[3][2],piCHdom[3][2],piHHdom[3][2]; double piCC[4][4][9][64],piCH[4][4][9][64],piHH[4][4][9][64]; double Tijdom[3][2],Tijc[4][4][9][64]; // spline knot values + double PCCf_2_0; double PCCf[5][5],PCCdfdx[5][5],PCCdfdy[5][5],PCHf[5][5]; double PCHdfdx[5][5],PCHdfdy[5][5]; double piCCf[5][5][11],piCCdfdx[5][5][11]; double piCCdfdy[5][5][11],piCCdfdz[5][5][11]; double piCHf[5][5][11],piCHdfdx[5][5][11]; double piCHdfdy[5][5][11],piCHdfdz[5][5][11]; double piHHf[5][5][11],piHHdfdx[5][5][11]; double piHHdfdy[5][5][11],piHHdfdz[5][5][11]; double Tf[5][5][10],Tdfdx[5][5][10],Tdfdy[5][5][10],Tdfdz[5][5][10]; void REBO_neigh(); void FREBO(int, int); void FLJ(int, int); void TORSION(int, int); double bondorder(int, int, double *, double, double, double **, int); double bondorderLJ(int, int, double *, double, double, double *, double, double **, int); double gSpline(double, double, int, double *, double *); double PijSpline(double, double, int, int, double *); double piRCSpline(double, double, double, int, int, double *); double TijSpline(double, double, double, double *); void read_file(char *); double Sp5th(double, double *, double *); double Spbicubic(double, double, double *, double *); double Sptricubic(double, double, double, double *, double *); void spline_init(); void allocate(); // ---------------------------------------------------------------------- // S'(t) and S(t) cutoff functions // added to header for inlining // ---------------------------------------------------------------------- /* ---------------------------------------------------------------------- cutoff function Sprime return cutoff and dX = derivative no side effects ------------------------------------------------------------------------- */ inline double Sp(double Xij, double Xmin, double Xmax, double &dX) const { double cutoff; double t = (Xij-Xmin) / (Xmax-Xmin); if (t <= 0.0) { cutoff = 1.0; dX = 0.0; } else if (t >= 1.0) { cutoff = 0.0; dX = 0.0; } else { cutoff = 0.5 * (1.0+cos(t*MathConst::MY_PI)); dX = (-0.5*MathConst::MY_PI*sin(t*MathConst::MY_PI)) / (Xmax-Xmin); } return cutoff; }; /* ---------------------------------------------------------------------- LJ cutoff function Sp2 return cutoff and dX = derivative no side effects ------------------------------------------------------------------------- */ inline double Sp2(double Xij, double Xmin, double Xmax, double &dX) const { double cutoff; double t = (Xij-Xmin) / (Xmax-Xmin); if (t <= 0.0) { cutoff = 1.0; dX = 0.0; } else if (t >= 1.0) { cutoff = 0.0; dX = 0.0; } else { cutoff = (1.0-(t*t*(3.0-2.0*t))); dX = 6.0*(t*t-t) / (Xmax-Xmin); } return cutoff; }; /* kronecker delta function returning a double */ inline double kronecker(const int a, const int b) const { return (a == b) ? 1.0 : 0.0; }; }; } #endif #endif /* ERROR/WARNING messages: E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. E: Incorrect args for pair coefficients Self-explanatory. Check the input script or data file. E: Pair style AIREBO requires atom IDs This is a requirement to use the AIREBO potential. E: Pair style AIREBO requires newton pair on See the newton command. This is a restriction to use the AIREBO potential. E: All pair coeffs are not set All pair coefficients must be set in the data file or by the pair_coeff command before running a simulation. E: Neighbor list overflow, boost neigh_modify one There are too many neighbors of a single atom. Use the neigh_modify command to increase the max number of neighbors allowed for one atom. You may also want to boost the page size. E: Cannot open AIREBO potential file %s The specified AIREBO potential file cannot be opened. Check that the path and name are correct. */ diff --git a/src/MANYBODY/pair_rebo.cpp b/src/MANYBODY/pair_rebo.cpp index 5b28eae4d..1cec1aef4 100644 --- a/src/MANYBODY/pair_rebo.cpp +++ b/src/MANYBODY/pair_rebo.cpp @@ -1,33 +1,38 @@ /* ---------------------------------------------------------------------- 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 "pair_rebo.h" #include "error.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ PairREBO::PairREBO(LAMMPS *lmp) : PairAIREBO(lmp) {} /* ---------------------------------------------------------------------- global settings ------------------------------------------------------------------------- */ void PairREBO::settings(int narg, char **arg) { if (narg != 0) error->all(FLERR,"Illegal pair_style command"); cutlj = 0.0; ljflag = torflag = 0; + + // this one parameter for C-C interactions is different in REBO vs AIREBO + // see Favata, Micheletti, Ryu, Pugno, Comp Phys Comm (2016) + + PCCf_2_0 = 0.0; } diff --git a/src/USER-COLVARS/colvarproxy_lammps.cpp b/src/USER-COLVARS/colvarproxy_lammps.cpp index 5e63d07c3..dc97db194 100644 --- a/src/USER-COLVARS/colvarproxy_lammps.cpp +++ b/src/USER-COLVARS/colvarproxy_lammps.cpp @@ -1,476 +1,476 @@ #include #include "lammps.h" #include "atom.h" #include "error.h" #include "output.h" #include "random_park.h" #include "fix_colvars.h" #include "colvarmodule.h" #include "colvar.h" #include "colvarbias.h" #include "colvaratoms.h" #include "colvarproxy.h" #include "colvarproxy_lammps.h" #include #include #include #include #include #include #include #include #include #define HASH_FAIL -1 //////////////////////////////////////////////////////////////////////// // local helper functions // safely move filename to filename.extension static int my_backup_file(const char *filename, const char *extension) { struct stat sbuf; if (stat(filename, &sbuf) == 0) { if (!extension) extension = ".BAK"; char *backup = new char[strlen(filename)+strlen(extension)+1]; strcpy(backup, filename); strcat(backup, extension); #if defined(_WIN32) && !defined(__CYGWIN__) remove(backup); #endif if (rename(filename,backup)) { char *sys_err_msg = strerror(errno); if (!sys_err_msg) sys_err_msg = (char *) "(unknown error)"; fprintf(stderr,"Error renaming file %s to %s: %s\n", filename, backup, sys_err_msg); delete [] backup; return COLVARS_ERROR; } delete [] backup; } return COLVARS_OK; } //////////////////////////////////////////////////////////////////////// colvarproxy_lammps::colvarproxy_lammps(LAMMPS_NS::LAMMPS *lmp, const char *inp_name, const char *out_name, const int seed, const double temp, MPI_Comm root2root) : _lmp(lmp), inter_comm(root2root) { if (cvm::debug()) log("Initializing the colvars proxy object.\n"); _random = new LAMMPS_NS::RanPark(lmp,seed); first_timestep=true; total_force_requested=false; previous_step=-1; t_target=temp; do_exit=false; restart_every=0; // User-scripted forces are not available in LAMMPS force_script_defined = false; have_scripts = false; // set input restart name and strip the extension, if present input_prefix_str = std::string(inp_name ? inp_name : ""); if (input_prefix_str.rfind(".colvars.state") != std::string::npos) input_prefix_str.erase(input_prefix_str.rfind(".colvars.state"), std::string(".colvars.state").size()); // output prefix is always given output_prefix_str = std::string(out_name); // not so for restarts restart_output_prefix_str = std::string("rest"); // check if it is possible to save output configuration if ((!output_prefix_str.size()) && (!restart_output_prefix_str.size())) { fatal_error("Error: neither the final output state file or " "the output restart file could be defined, exiting.\n"); } // try to extract a restart prefix from a potential restart command. LAMMPS_NS::Output *outp = _lmp->output; if ((outp->restart_every_single > 0) && (outp->restart1 != 0)) { restart_output_prefix_str = std::string(outp->restart1); } else if ((outp->restart_every_double > 0) && (outp->restart2a != 0)) { restart_output_prefix_str = std::string(outp->restart2a); } // trim off unwanted stuff from the restart prefix if (restart_output_prefix_str.rfind(".*") != std::string::npos) restart_output_prefix_str.erase(restart_output_prefix_str.rfind(".*"),2); #if defined(_OPENMP) if (smp_thread_id() == 0) { omp_init_lock(&smp_lock_state); } #endif // initialize multi-replica support, if available if (replica_enabled()) { MPI_Comm_rank(inter_comm, &inter_me); MPI_Comm_size(inter_comm, &inter_num); } if (cvm::debug()) log("Done initializing the colvars proxy object.\n"); } void colvarproxy_lammps::init(const char *conf_file) { // create the colvarmodule instance colvars = new colvarmodule(this); cvm::log("Using LAMMPS interface, version "+ cvm::to_str(COLVARPROXY_VERSION)+".\n"); my_angstrom = _lmp->force->angstrom; my_boltzmann = _lmp->force->boltz; my_timestep = _lmp->update->dt * _lmp->force->femtosecond; // TODO move one or more of these to setup() if needed colvars->read_config_file(conf_file); colvars->setup_input(); colvars->setup_output(); if (_lmp->update->ntimestep != 0) { cvm::log("Initializing step number as firstTimestep.\n"); colvars->it = colvars->it_restart = _lmp->update->ntimestep; } if (cvm::debug()) { log("atoms_ids = "+cvm::to_str(atoms_ids)+"\n"); log("atoms_ncopies = "+cvm::to_str(atoms_ncopies)+"\n"); log("atoms_positions = "+cvm::to_str(atoms_positions)+"\n"); log(cvm::line_marker); log("Info: done initializing the colvars proxy object.\n"); } } colvarproxy_lammps::~colvarproxy_lammps() { delete _random; if (colvars != NULL) { colvars->write_output_files(); delete colvars; colvars = NULL; } } // re-initialize data where needed int colvarproxy_lammps::setup() { my_timestep = _lmp->update->dt * _lmp->force->femtosecond; return colvars->setup(); } // trigger colvars computation double colvarproxy_lammps::compute() { if (first_timestep) { first_timestep = false; } else { // Use the time step number inherited from LAMMPS if ( _lmp->update->ntimestep - previous_step == 1 ) colvars->it++; // Other cases could mean: // - run 0 // - beginning of a new run statement // then the internal counter should not be incremented } previous_step = _lmp->update->ntimestep; if (cvm::debug()) { - cvm::log(cvm::line_marker+ + cvm::log(std::string(cvm::line_marker)+ "colvarproxy_lammps, step no. "+cvm::to_str(colvars->it)+"\n"+ "Updating internal data.\n"); } // zero the forces on the atoms, so that they can be accumulated by the colvars for (size_t i = 0; i < atoms_new_colvar_forces.size(); i++) { atoms_new_colvar_forces[i].reset(); } bias_energy = 0.0; if (cvm::debug()) { log("atoms_ids = "+cvm::to_str(atoms_ids)+"\n"); log("atoms_ncopies = "+cvm::to_str(atoms_ncopies)+"\n"); log("atoms_positions = "+cvm::to_str(atoms_positions)+"\n"); log("atoms_new_colvar_forces = "+cvm::to_str(atoms_new_colvar_forces)+"\n"); } // call the collective variable module colvars->calc(); if (cvm::debug()) { log("atoms_ids = "+cvm::to_str(atoms_ids)+"\n"); log("atoms_ncopies = "+cvm::to_str(atoms_ncopies)+"\n"); log("atoms_positions = "+cvm::to_str(atoms_positions)+"\n"); log("atoms_new_colvar_forces = "+cvm::to_str(atoms_new_colvar_forces)+"\n"); } return bias_energy; } void colvarproxy_lammps::serialize_status(std::string &rst) { std::ostringstream os; colvars->write_restart(os); rst = os.str(); } // set status from string bool colvarproxy_lammps::deserialize_status(std::string &rst) { std::istringstream is; is.str(rst); if (!colvars->read_restart(is)) { return false; } else { return true; } } cvm::rvector colvarproxy_lammps::position_distance(cvm::atom_pos const &pos1, cvm::atom_pos const &pos2) { double xtmp = pos2.x - pos1.x; double ytmp = pos2.y - pos1.y; double ztmp = pos2.z - pos1.z; _lmp->domain->minimum_image(xtmp,ytmp,ztmp); return cvm::rvector(xtmp, ytmp, ztmp); } cvm::real colvarproxy_lammps::position_dist2(cvm::atom_pos const &pos1, cvm::atom_pos const &pos2) { double xtmp = pos2.x - pos1.x; double ytmp = pos2.y - pos1.y; double ztmp = pos2.z - pos1.z; _lmp->domain->minimum_image(xtmp,ytmp,ztmp); return cvm::real(xtmp*xtmp + ytmp*ytmp + ztmp*ztmp); } void colvarproxy_lammps::select_closest_image(cvm::atom_pos &pos, cvm::atom_pos const &ref) { double xtmp = pos.x - ref.x; double ytmp = pos.y - ref.y; double ztmp = pos.z - ref.z; _lmp->domain->minimum_image(xtmp,ytmp,ztmp); pos.x = ref.x + xtmp; pos.y = ref.y + ytmp; pos.z = ref.z + ztmp; } void colvarproxy_lammps::log(std::string const &message) { std::istringstream is(message); std::string line; while (std::getline(is, line)) { if (_lmp->screen) fprintf(_lmp->screen,"colvars: %s\n",line.c_str()); if (_lmp->logfile) fprintf(_lmp->logfile,"colvars: %s\n",line.c_str()); } } void colvarproxy_lammps::error(std::string const &message) { // In LAMMPS, all errors are fatal fatal_error(message); } void colvarproxy_lammps::fatal_error(std::string const &message) { log(message); // if (!cvm::debug()) // log("If this error message is unclear, try recompiling the " // "colvars library and LAMMPS with -DCOLVARS_DEBUG.\n"); _lmp->error->one(FLERR, "Fatal error in the collective variables module.\n"); } void colvarproxy_lammps::exit(std::string const &message) { log(message); log("Request to exit the simulation made.\n"); do_exit=true; } int colvarproxy_lammps::backup_file(char const *filename) { if (std::string(filename).rfind(std::string(".colvars.state")) != std::string::npos) { return my_backup_file(filename, ".old"); } else { return my_backup_file(filename, ".BAK"); } } #if defined(_OPENMP) // SMP support int colvarproxy_lammps::smp_enabled() { return COLVARS_OK; } int colvarproxy_lammps::smp_colvars_loop() { colvarmodule *cv = this->colvars; #pragma omp parallel for for (size_t i = 0; i < cv->colvars_smp.size(); i++) { if (cvm::debug()) { cvm::log("Calculating colvar \""+cv->colvars_smp[i]->name+"\" on thread "+cvm::to_str(smp_thread_id())+"\n"); } cv->colvars_smp[i]->calc_cvcs(cv->colvars_smp_items[i], 1); } return cvm::get_error(); } int colvarproxy_lammps::smp_biases_loop() { colvarmodule *cv = this->colvars; #pragma omp parallel for for (size_t i = 0; i < cv->biases.size(); i++) { if (cvm::debug()) { cvm::log("Calculating bias \""+cv->biases[i]->name+"\" on thread "+cvm::to_str(smp_thread_id())+"\n"); } cv->biases[i]->update(); } return cvm::get_error(); } int colvarproxy_lammps::smp_thread_id() { return omp_get_thread_num(); } int colvarproxy_lammps::smp_num_threads() { return omp_get_max_threads(); } int colvarproxy_lammps::smp_lock() { omp_set_lock(&smp_lock_state); return COLVARS_OK; } int colvarproxy_lammps::smp_trylock() { return omp_test_lock(&smp_lock_state) ? COLVARS_OK : COLVARS_ERROR; } int colvarproxy_lammps::smp_unlock() { omp_unset_lock(&smp_lock_state); return COLVARS_OK; } #endif // multi-replica support void colvarproxy_lammps::replica_comm_barrier() { MPI_Barrier(inter_comm); } int colvarproxy_lammps::replica_comm_recv(char* msg_data, int buf_len, int src_rep) { MPI_Status status; int retval; retval = MPI_Recv(msg_data,buf_len,MPI_CHAR,src_rep,0,inter_comm,&status); if (retval == MPI_SUCCESS) { MPI_Get_count(&status, MPI_CHAR, &retval); } else retval = 0; return retval; } int colvarproxy_lammps::replica_comm_send(char* msg_data, int msg_len, int dest_rep) { int retval; retval = MPI_Send(msg_data,msg_len,MPI_CHAR,dest_rep,0,inter_comm); if (retval == MPI_SUCCESS) { retval = msg_len; } else retval = 0; return retval; } int colvarproxy_lammps::check_atom_id(int atom_number) { int const aid = atom_number; if (cvm::debug()) log("Adding atom "+cvm::to_str(atom_number)+ " for collective variables calculation.\n"); // TODO add upper boundary check? if ( (aid < 0) ) { cvm::error("Error: invalid atom number specified, "+ cvm::to_str(atom_number)+"\n", INPUT_ERROR); return INPUT_ERROR; } return aid; } int colvarproxy_lammps::init_atom(int atom_number) { int aid = atom_number; for (size_t i = 0; i < atoms_ids.size(); i++) { if (atoms_ids[i] == aid) { // this atom id was already recorded atoms_ncopies[i] += 1; return i; } } aid = check_atom_id(atom_number); if (aid < 0) { return aid; } int const index = colvarproxy::add_atom_slot(aid); // add entries for the LAMMPS-specific fields atoms_types.push_back(0); return index; } diff --git a/src/USER-DPD/atom_vec_dpd.cpp b/src/USER-DPD/atom_vec_dpd.cpp index 2bd460475..399383ec1 100644 --- a/src/USER-DPD/atom_vec_dpd.cpp +++ b/src/USER-DPD/atom_vec_dpd.cpp @@ -1,937 +1,939 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: James Larentzos (U.S. Army Research Laboratory) ------------------------------------------------------------------------- */ #include #include "atom_vec_dpd.h" #include "atom.h" #include "comm.h" #include "domain.h" #include "modify.h" #include "fix.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ AtomVecDPD::AtomVecDPD(LAMMPS *lmp) : AtomVec(lmp) { molecular = 0; mass_type = 1; comm_x_only = comm_f_only = 0; // we communicate not only x forward but also dpdTheta size_forward = 7; // 3 + dpdTheta + uCond + uMech + uChem size_reverse = 3; // 3 size_border = 12; // 6 + dpdTheta + uCond + uMech + uChem + uCG + uCGnew size_velocity = 3; size_data_atom = 6; // we read id + type + dpdTheta + x + y + z size_data_vel = 4; xcol_data = 4; // 1=id 2=type 3=dpdTheta 4=x atom->rho_flag = 1; atom->dpd_flag = 1; } /* ---------------------------------------------------------------------- grow atom arrays n = 0 grows arrays by a chunk n > 0 allocates arrays to size n ------------------------------------------------------------------------- */ void AtomVecDPD::grow(int n) { if (n == 0) grow_nmax(); else nmax = n; atom->nmax = nmax; if (nmax < 0) error->one(FLERR,"Per-processor system is too big"); tag = memory->grow(atom->tag,nmax,"atom:tag"); type = memory->grow(atom->type,nmax,"atom:type"); mask = memory->grow(atom->mask,nmax,"atom:mask"); image = memory->grow(atom->image,nmax,"atom:image"); x = memory->grow(atom->x,nmax,3,"atom:x"); v = memory->grow(atom->v,nmax,3,"atom:v"); f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f"); rho = memory->grow(atom->rho, nmax, "atom:rho"); dpdTheta = memory->grow(atom->dpdTheta, nmax, "atom:dpdTheta"); uCond = memory->grow(atom->uCond,nmax,"atom:uCond"); uMech = memory->grow(atom->uMech,nmax,"atom:uMech"); uChem = memory->grow(atom->uChem,nmax,"atom:uChem"); uCG = memory->grow(atom->uCG,nmax,"atom:uCG"); uCGnew = memory->grow(atom->uCGnew,nmax,"atom:uCGnew"); duChem = memory->grow(atom->duChem,nmax,"atom:duChem"); if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax); } /* ---------------------------------------------------------------------- reset local array ptrs ------------------------------------------------------------------------- */ void AtomVecDPD::grow_reset() { tag = atom->tag; type = atom->type; mask = atom->mask; image = atom->image; x = atom->x; v = atom->v; f = atom->f; rho = atom->rho; dpdTheta = atom->dpdTheta; uCond = atom->uCond; uMech = atom->uMech; uChem = atom->uChem; uCG = atom->uCG; uCGnew = atom->uCGnew; duChem = atom->duChem; } /* ---------------------------------------------------------------------- copy atom I info to atom J ------------------------------------------------------------------------- */ void AtomVecDPD::copy(int i, int j, int delflag) { tag[j] = tag[i]; type[j] = type[i]; mask[j] = mask[i]; image[j] = image[i]; x[j][0] = x[i][0]; x[j][1] = x[i][1]; x[j][2] = x[i][2]; v[j][0] = v[i][0]; v[j][1] = v[i][1]; v[j][2] = v[i][2]; dpdTheta[j] = dpdTheta[i]; uCond[j] = uCond[i]; uMech[j] = uMech[i]; uChem[j] = uChem[i]; uCG[j] = uCG[i]; uCGnew[j] = uCGnew[i]; if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); } /* ---------------------------------------------------------------------- */ int AtomVecDPD::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; m = 0; if (pbc_flag == 0) { for (i = 0; i < n; i++) { j = list[i]; buf[m++] = x[j][0]; buf[m++] = x[j][1]; buf[m++] = x[j][2]; buf[m++] = dpdTheta[j]; buf[m++] = uCond[j]; buf[m++] = uMech[j]; buf[m++] = uChem[j]; } } else { if (domain->triclinic == 0) { dx = pbc[0]*domain->xprd; dy = pbc[1]*domain->yprd; dz = pbc[2]*domain->zprd; } else { dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; dz = pbc[2]*domain->zprd; } for (i = 0; i < n; i++) { j = list[i]; buf[m++] = x[j][0] + dx; buf[m++] = x[j][1] + dy; buf[m++] = x[j][2] + dz; buf[m++] = dpdTheta[j]; buf[m++] = uCond[j]; buf[m++] = uMech[j]; buf[m++] = uChem[j]; } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecDPD::pack_comm_vel(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz,dvx,dvy,dvz; m = 0; if (pbc_flag == 0) { for (i = 0; i < n; i++) { j = list[i]; buf[m++] = x[j][0]; buf[m++] = x[j][1]; buf[m++] = x[j][2]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = dpdTheta[j]; buf[m++] = uCond[j]; buf[m++] = uMech[j]; buf[m++] = uChem[j]; } } else { if (domain->triclinic == 0) { dx = pbc[0]*domain->xprd; dy = pbc[1]*domain->yprd; dz = pbc[2]*domain->zprd; } else { dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; dz = pbc[2]*domain->zprd; } if (!deform_vremap) { for (i = 0; i < n; i++) { j = list[i]; buf[m++] = x[j][0] + dx; buf[m++] = x[j][1] + dy; buf[m++] = x[j][2] + dz; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = dpdTheta[j]; buf[m++] = uCond[j]; buf[m++] = uMech[j]; buf[m++] = uChem[j]; } } else { dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; dvz = pbc[2]*h_rate[2]; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = x[j][0] + dx; buf[m++] = x[j][1] + dy; buf[m++] = x[j][2] + dz; if (mask[i] & deform_groupbit) { buf[m++] = v[j][0] + dvx; buf[m++] = v[j][1] + dvy; buf[m++] = v[j][2] + dvz; } else { buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; } buf[m++] = dpdTheta[j]; buf[m++] = uCond[j]; buf[m++] = uMech[j]; buf[m++] = uChem[j]; } } } return m; } /* ---------------------------------------------------------------------- */ void AtomVecDPD::unpack_comm(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) { x[i][0] = buf[m++]; x[i][1] = buf[m++]; x[i][2] = buf[m++]; dpdTheta[i] = buf[m++]; uCond[i] = buf[m++]; uMech[i] = buf[m++]; uChem[i] = buf[m++]; } } /* ---------------------------------------------------------------------- */ void AtomVecDPD::unpack_comm_vel(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) { x[i][0] = buf[m++]; x[i][1] = buf[m++]; x[i][2] = buf[m++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; dpdTheta[i] = buf[m++]; uCond[i] = buf[m++]; uMech[i] = buf[m++]; uChem[i] = buf[m++]; } } /* ---------------------------------------------------------------------- */ int AtomVecDPD::pack_reverse(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) { buf[m++] = f[i][0]; buf[m++] = f[i][1]; buf[m++] = f[i][2]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecDPD::unpack_reverse(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; f[j][0] += buf[m++]; f[j][1] += buf[m++]; f[j][2] += buf[m++]; } } /* ---------------------------------------------------------------------- */ int AtomVecDPD::pack_border(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; m = 0; if (pbc_flag == 0) { for (i = 0; i < n; i++) { j = list[i]; buf[m++] = x[j][0]; buf[m++] = x[j][1]; buf[m++] = x[j][2]; buf[m++] = ubuf(tag[j]).d; buf[m++] = ubuf(type[j]).d; buf[m++] = ubuf(mask[j]).d; buf[m++] = dpdTheta[j]; buf[m++] = uCond[j]; buf[m++] = uMech[j]; buf[m++] = uChem[j]; buf[m++] = uCG[j]; buf[m++] = uCGnew[j]; } } else { if (domain->triclinic == 0) { dx = pbc[0]*domain->xprd; dy = pbc[1]*domain->yprd; dz = pbc[2]*domain->zprd; } else { dx = pbc[0]; dy = pbc[1]; dz = pbc[2]; } for (i = 0; i < n; i++) { j = list[i]; buf[m++] = x[j][0] + dx; buf[m++] = x[j][1] + dy; buf[m++] = x[j][2] + dz; buf[m++] = ubuf(tag[j]).d; buf[m++] = ubuf(type[j]).d; buf[m++] = ubuf(mask[j]).d; buf[m++] = dpdTheta[j]; buf[m++] = uCond[j]; buf[m++] = uMech[j]; buf[m++] = uChem[j]; buf[m++] = uCG[j]; buf[m++] = uCGnew[j]; } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecDPD::pack_border_vel(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz,dvx,dvy,dvz; m = 0; if (pbc_flag == 0) { for (i = 0; i < n; i++) { j = list[i]; buf[m++] = x[j][0]; buf[m++] = x[j][1]; buf[m++] = x[j][2]; buf[m++] = ubuf(tag[j]).d; buf[m++] = ubuf(type[j]).d; buf[m++] = ubuf(mask[j]).d; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = dpdTheta[j]; buf[m++] = uCond[j]; buf[m++] = uMech[j]; buf[m++] = uChem[j]; buf[m++] = uCG[j]; buf[m++] = uCGnew[j]; } } else { if (domain->triclinic == 0) { dx = pbc[0]*domain->xprd; dy = pbc[1]*domain->yprd; dz = pbc[2]*domain->zprd; } else { dx = pbc[0]; dy = pbc[1]; dz = pbc[2]; } if (!deform_vremap) { for (i = 0; i < n; i++) { j = list[i]; buf[m++] = x[j][0] + dx; buf[m++] = x[j][1] + dy; buf[m++] = x[j][2] + dz; buf[m++] = ubuf(tag[j]).d; buf[m++] = ubuf(type[j]).d; buf[m++] = ubuf(mask[j]).d; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = dpdTheta[j]; buf[m++] = uCond[j]; buf[m++] = uMech[j]; buf[m++] = uChem[j]; buf[m++] = uCG[j]; buf[m++] = uCGnew[j]; } } else { dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; dvz = pbc[2]*h_rate[2]; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = x[j][0] + dx; buf[m++] = x[j][1] + dy; buf[m++] = x[j][2] + dz; buf[m++] = ubuf(tag[j]).d; buf[m++] = ubuf(type[j]).d; buf[m++] = ubuf(mask[j]).d; if (mask[i] & deform_groupbit) { buf[m++] = v[j][0] + dvx; buf[m++] = v[j][1] + dvy; buf[m++] = v[j][2] + dvz; } else { buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; } buf[m++] = dpdTheta[j]; buf[m++] = uCond[j]; buf[m++] = uMech[j]; buf[m++] = uChem[j]; buf[m++] = uCG[j]; buf[m++] = uCGnew[j]; } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecDPD::pack_comm_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = dpdTheta[j]; buf[m++] = uCond[j]; buf[m++] = uMech[j]; buf[m++] = uChem[j]; buf[m++] = uCG[j]; buf[m++] = uCGnew[j]; } return m; } /* ---------------------------------------------------------------------- */ int AtomVecDPD::pack_border_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = dpdTheta[j]; buf[m++] = uCond[j]; buf[m++] = uMech[j]; buf[m++] = uChem[j]; buf[m++] = uCG[j]; buf[m++] = uCGnew[j]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecDPD::unpack_border(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) { if (i == nmax) grow(0); x[i][0] = buf[m++]; x[i][1] = buf[m++]; x[i][2] = buf[m++]; tag[i] = (tagint) ubuf(buf[m++]).i; type[i] = (int) ubuf(buf[m++]).i; mask[i] = (int) ubuf(buf[m++]).i; dpdTheta[i] = buf[m++]; uCond[i] = buf[m++]; uMech[i] = buf[m++]; uChem[i] = buf[m++]; uCG[i] = buf[m++]; uCGnew[i] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ void AtomVecDPD::unpack_border_vel(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) { if (i == nmax) grow(0); x[i][0] = buf[m++]; x[i][1] = buf[m++]; x[i][2] = buf[m++]; tag[i] = (tagint) ubuf(buf[m++]).i; type[i] = (int) ubuf(buf[m++]).i; mask[i] = (int) ubuf(buf[m++]).i; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; dpdTheta[i] = buf[m++]; uCond[i] = buf[m++]; uMech[i] = buf[m++]; uChem[i] = buf[m++]; uCG[i] = buf[m++]; uCGnew[i] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ int AtomVecDPD::unpack_comm_hybrid(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) { dpdTheta[i] = buf[m++]; uCond[i] = buf[m++]; uMech[i] = buf[m++]; uChem[i] = buf[m++]; + uCG[i] = buf[m++]; + uCGnew[i] = buf[m++]; } return m; } /* ---------------------------------------------------------------------- */ int AtomVecDPD::unpack_border_hybrid(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) { dpdTheta[i] = buf[m++]; uCond[i] = buf[m++]; uMech[i] = buf[m++]; uChem[i] = buf[m++]; uCG[i] = buf[m++]; uCGnew[i] = buf[m++]; } return m; } /* ---------------------------------------------------------------------- pack data for atom I for sending to another proc xyz must be 1st 3 values, so comm::exchange() can test on them ------------------------------------------------------------------------- */ int AtomVecDPD::pack_exchange(int i, double *buf) { int m = 1; buf[m++] = x[i][0]; buf[m++] = x[i][1]; buf[m++] = x[i][2]; buf[m++] = v[i][0]; buf[m++] = v[i][1]; buf[m++] = v[i][2]; buf[m++] = ubuf(tag[i]).d; buf[m++] = ubuf(type[i]).d; buf[m++] = ubuf(mask[i]).d; buf[m++] = ubuf(image[i]).d; buf[m++] = dpdTheta[i]; buf[m++] = uCond[i]; buf[m++] = uMech[i]; buf[m++] = uChem[i]; buf[m++] = uCG[i]; buf[m++] = uCGnew[i]; if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]); buf[0] = m; return m; } /* ---------------------------------------------------------------------- */ int AtomVecDPD::unpack_exchange(double *buf) { int nlocal = atom->nlocal; if (nlocal == nmax) grow(0); int m = 1; x[nlocal][0] = buf[m++]; x[nlocal][1] = buf[m++]; x[nlocal][2] = buf[m++]; v[nlocal][0] = buf[m++]; v[nlocal][1] = buf[m++]; v[nlocal][2] = buf[m++]; tag[nlocal] = (tagint) ubuf(buf[m++]).i; type[nlocal] = (int) ubuf(buf[m++]).i; mask[nlocal] = (int) ubuf(buf[m++]).i; image[nlocal] = (imageint) ubuf(buf[m++]).i; dpdTheta[nlocal] = buf[m++]; uCond[nlocal] = buf[m++]; uMech[nlocal] = buf[m++]; uChem[nlocal] = buf[m++]; uCG[nlocal] = buf[m++]; uCGnew[nlocal] = buf[m++]; if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) m += modify->fix[atom->extra_grow[iextra]]-> unpack_exchange(nlocal,&buf[m]); atom->nlocal++; return m; } /* ---------------------------------------------------------------------- size of restart data for all atoms owned by this proc include extra data stored by fixes ------------------------------------------------------------------------- */ int AtomVecDPD::size_restart() { int i; int nlocal = atom->nlocal; int n = 15 * nlocal; // 11 + dpdTheta + uCond + uMech + uChem if (atom->nextra_restart) for (int iextra = 0; iextra < atom->nextra_restart; iextra++) for (i = 0; i < nlocal; i++) n += modify->fix[atom->extra_restart[iextra]]->size_restart(i); return n; } /* ---------------------------------------------------------------------- pack atom I's data for restart file including extra quantities xyz must be 1st 3 values, so that read_restart can test on them molecular types may be negative, but write as positive ------------------------------------------------------------------------- */ int AtomVecDPD::pack_restart(int i, double *buf) { int m = 1; buf[m++] = x[i][0]; buf[m++] = x[i][1]; buf[m++] = x[i][2]; buf[m++] = ubuf(tag[i]).d; buf[m++] = ubuf(type[i]).d; buf[m++] = ubuf(mask[i]).d; buf[m++] = ubuf(image[i]).d; buf[m++] = v[i][0]; buf[m++] = v[i][1]; buf[m++] = v[i][2]; buf[m++] = dpdTheta[i]; buf[m++] = uCond[i]; buf[m++] = uMech[i]; buf[m++] = uChem[i]; if (atom->nextra_restart) for (int iextra = 0; iextra < atom->nextra_restart; iextra++) m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]); buf[0] = m; return m; } /* ---------------------------------------------------------------------- unpack data for one atom from restart file including extra quantities ------------------------------------------------------------------------- */ int AtomVecDPD::unpack_restart(double *buf) { int nlocal = atom->nlocal; if (nlocal == nmax) { grow(0); if (atom->nextra_store) memory->grow(atom->extra,nmax,atom->nextra_store,"atom:extra"); } int m = 1; x[nlocal][0] = buf[m++]; x[nlocal][1] = buf[m++]; x[nlocal][2] = buf[m++]; tag[nlocal] = (tagint) ubuf(buf[m++]).i; type[nlocal] = (int) ubuf(buf[m++]).i; mask[nlocal] = (int) ubuf(buf[m++]).i; image[nlocal] = (imageint) ubuf(buf[m++]).i; v[nlocal][0] = buf[m++]; v[nlocal][1] = buf[m++]; v[nlocal][2] = buf[m++]; dpdTheta[nlocal] = buf[m++]; uCond[nlocal] = buf[m++]; uMech[nlocal] = buf[m++]; uChem[nlocal] = buf[m++]; double **extra = atom->extra; if (atom->nextra_store) { int size = static_cast (buf[0]) - m; for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++]; } atom->nlocal++; return m; } /* ---------------------------------------------------------------------- create one atom of itype at coord set other values to defaults ------------------------------------------------------------------------- */ void AtomVecDPD::create_atom(int itype, double *coord) { int nlocal = atom->nlocal; if (nlocal == nmax) grow(0); tag[nlocal] = 0; type[nlocal] = itype; x[nlocal][0] = coord[0]; x[nlocal][1] = coord[1]; x[nlocal][2] = coord[2]; mask[nlocal] = 1; image[nlocal] = ((imageint) IMGMAX << IMG2BITS) | ((imageint) IMGMAX << IMGBITS) | IMGMAX; v[nlocal][0] = 0.0; v[nlocal][1] = 0.0; v[nlocal][2] = 0.0; rho[nlocal] = 0.0; dpdTheta[nlocal] = 0.0; uCond[nlocal] = 0.0; uMech[nlocal] = 0.0; uChem[nlocal] = 0.0; uCG[nlocal] = 0.0; uCGnew[nlocal] = 0.0; duChem[nlocal] = 0.0; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecDPD::data_atom(double *coord, tagint imagetmp, char **values) { int nlocal = atom->nlocal; if (nlocal == nmax) grow(0); tag[nlocal] = ATOTAGINT(values[0]); type[nlocal] = atoi(values[1]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) error->one(FLERR,"Invalid atom type in Atoms section of data file"); dpdTheta[nlocal] = atof(values[2]); if (dpdTheta[nlocal] <= 0) error->one(FLERR,"Internal temperature in Atoms section of date file must be > zero"); x[nlocal][0] = coord[0]; x[nlocal][1] = coord[1]; x[nlocal][2] = coord[2]; image[nlocal] = imagetmp; mask[nlocal] = 1; v[nlocal][0] = 0.0; v[nlocal][1] = 0.0; v[nlocal][2] = 0.0; rho[nlocal] = 0.0; uCond[nlocal] = 0.0; uMech[nlocal] = 0.0; uChem[nlocal] = 0.0; uCG[nlocal] = 0.0; uCGnew[nlocal] = 0.0; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack hybrid quantities from one line in Atoms section of data file initialize other atom quantities for this sub-style ------------------------------------------------------------------------- */ int AtomVecDPD::data_atom_hybrid(int nlocal, char **values) { dpdTheta[nlocal] = atof(values[0]); return 1; } /* ---------------------------------------------------------------------- pack atom info for data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecDPD::pack_data(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = ubuf(tag[i]).d; buf[i][1] = ubuf(type[i]).d; buf[i][2] = dpdTheta[i]; buf[i][3] = x[i][0]; buf[i][4] = x[i][1]; buf[i][5] = x[i][2]; buf[i][6] = ubuf((image[i] & IMGMASK) - IMGMAX).d; buf[i][7] = ubuf((image[i] >> IMGBITS & IMGMASK) - IMGMAX).d; buf[i][8] = ubuf((image[i] >> IMG2BITS) - IMGMAX).d; } } /* ---------------------------------------------------------------------- pack hybrid atom info for data file ------------------------------------------------------------------------- */ int AtomVecDPD::pack_data_hybrid(int i, double *buf) { buf[0] = dpdTheta[i]; return 1; } /* ---------------------------------------------------------------------- write atom info to data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecDPD::write_data(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,TAGINT_FORMAT " %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n", (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i, buf[i][2],buf[i][3],buf[i][4],buf[i][5], (int) ubuf(buf[i][6]).i,(int) ubuf(buf[i][7]).i, (int) ubuf(buf[i][8]).i); } /* ---------------------------------------------------------------------- write hybrid atom info to data file ------------------------------------------------------------------------- */ int AtomVecDPD::write_data_hybrid(FILE *fp, double *buf) { fprintf(fp," %-1.16e",buf[0]); return 1; } /* ---------------------------------------------------------------------- return # of bytes of allocated memory ------------------------------------------------------------------------- */ bigint AtomVecDPD::memory_usage() { bigint bytes = 0; if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax); if (atom->memcheck("type")) bytes += memory->usage(type,nmax); if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax); if (atom->memcheck("image")) bytes += memory->usage(image,nmax); if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3); if (atom->memcheck("rho")) bytes += memory->usage(rho,nmax); if (atom->memcheck("dpdTheta")) bytes += memory->usage(dpdTheta,nmax); if (atom->memcheck("uCond")) bytes += memory->usage(uCond,nmax); if (atom->memcheck("uMech")) bytes += memory->usage(uMech,nmax); if (atom->memcheck("uChem")) bytes += memory->usage(uChem,nmax); if (atom->memcheck("uCG")) bytes += memory->usage(uCG,nmax); if (atom->memcheck("uCGnew")) bytes += memory->usage(uCGnew,nmax); if (atom->memcheck("duChem")) bytes += memory->usage(duChem,nmax); return bytes; } diff --git a/src/USER-DPD/compute_dpd_atom.cpp b/src/USER-DPD/compute_dpd_atom.cpp index 10f5d8203..ffac09c48 100644 --- a/src/USER-DPD/compute_dpd_atom.cpp +++ b/src/USER-DPD/compute_dpd_atom.cpp @@ -1,109 +1,109 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: James Larentzos (U.S. Army Research Laboratory) ------------------------------------------------------------------------- */ -#include "math.h" +#include #include #include #include "compute_dpd_atom.h" #include "atom.h" #include "update.h" #include "modify.h" #include "domain.h" #include "group.h" #include "memory.h" #include "error.h" #include "comm.h" #include using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ ComputeDpdAtom::ComputeDpdAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { if (narg != 3) error->all(FLERR,"Illegal compute dpd/atom command"); peratom_flag = 1; size_peratom_cols = 4; nmax = 0; dpdAtom = NULL; if (atom->dpd_flag != 1) error->all(FLERR,"compute dpd requires atom_style with internal temperature and energies (e.g. dpd)"); } /* ---------------------------------------------------------------------- */ ComputeDpdAtom::~ComputeDpdAtom() { memory->destroy(dpdAtom); } /* ---------------------------------------------------------------------- */ void ComputeDpdAtom::init() { int count = 0; for (int i = 0; i < modify->ncompute; i++) if (strcmp(modify->compute[i]->style,"dpd/atom") == 0) count++; if (count > 1 && comm->me == 0) error->warning(FLERR,"More than one compute dpd/atom command"); } /* ---------------------------------------------------------------------- gather compute vector data from other nodes ------------------------------------------------------------------------- */ void ComputeDpdAtom::compute_peratom() { invoked_peratom = update->ntimestep; double *uCond = atom->uCond; double *uMech = atom->uMech; double *uChem = atom->uChem; double *dpdTheta = atom->dpdTheta; int nlocal = atom->nlocal; int *mask = atom->mask; if (nlocal > nmax) { memory->destroy(dpdAtom); nmax = atom->nmax; memory->create(dpdAtom,nmax,size_peratom_cols,"dpd/atom:dpdAtom"); array_atom = dpdAtom; } for (int i = 0; i < nlocal; i++){ if (mask[i] & groupbit){ dpdAtom[i][0] = uCond[i]; dpdAtom[i][1] = uMech[i]; dpdAtom[i][2] = uChem[i]; dpdAtom[i][3] = dpdTheta[i]; } } } /* ---------------------------------------------------------------------- memory usage of local atom-based array ------------------------------------------------------------------------- */ double ComputeDpdAtom::memory_usage() { double bytes = size_peratom_cols * nmax * sizeof(double); return bytes; } diff --git a/src/USER-DPD/pair_exp6_rx.cpp b/src/USER-DPD/pair_exp6_rx.cpp index 697f94ec7..060ef2d7c 100644 --- a/src/USER-DPD/pair_exp6_rx.cpp +++ b/src/USER-DPD/pair_exp6_rx.cpp @@ -1,1137 +1,1131 @@ /* ---------------------------------------------------------------------- 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 #include #include #include #include "pair_exp6_rx.h" #include "atom.h" #include "comm.h" #include "force.h" #include "neigh_list.h" #include "math_const.h" #include "math_special.h" #include "memory.h" #include "error.h" #include "modify.h" #include "fix.h" -#include "float.h" +#include using namespace LAMMPS_NS; using namespace MathConst; using namespace MathSpecial; #define MAXLINE 1024 #define DELTA 4 #define oneFluidApproxParameter (-1) #define isOneFluidApprox(_site) ( (_site) == oneFluidApproxParameter ) #define exp6PotentialType (1) #define isExp6PotentialType(_type) ( (_type) == exp6PotentialType ) // Create a structure to hold the parameter data for all // local and neighbor particles. Pack inside this struct // to avoid any name clashes. struct PairExp6ParamDataType { int n; double *epsilon1, *alpha1, *rm1, *fraction1, *epsilon2, *alpha2, *rm2, *fraction2, *epsilonOld1, *alphaOld1, *rmOld1, *fractionOld1, *epsilonOld2, *alphaOld2, *rmOld2, *fractionOld2; // Default constructor -- nullify everything. PairExp6ParamDataType(void) : n(0), epsilon1(NULL), alpha1(NULL), rm1(NULL), fraction1(NULL), epsilon2(NULL), alpha2(NULL), rm2(NULL), fraction2(NULL), epsilonOld1(NULL), alphaOld1(NULL), rmOld1(NULL), fractionOld1(NULL), epsilonOld2(NULL), alphaOld2(NULL), rmOld2(NULL), fractionOld2(NULL) {} }; /* ---------------------------------------------------------------------- */ PairExp6rx::PairExp6rx(LAMMPS *lmp) : Pair(lmp) { writedata = 1; nspecies = 0; nparams = maxparam = 0; params = NULL; mol2param = NULL; } /* ---------------------------------------------------------------------- */ PairExp6rx::~PairExp6rx() { for (int i=0; i < nparams; ++i) { delete[] params[i].name; delete[] params[i].potential; } memory->destroy(params); memory->destroy(mol2param); if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); memory->destroy(cut); } } /* ---------------------------------------------------------------------- */ void PairExp6rx::compute(int eflag, int vflag) { int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,evdwlOld,fpair; double rsq,r2inv,r6inv,forceExp6,factor_lj; double rCut,rCutInv,rCut2inv,rCut6inv,rCutExp,urc,durc; double rm2ij,rm6ij; double r,rexp; int *ilist,*jlist,*numneigh,**firstneigh; evdwlOld = 0.0; evdwl = 0.0; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; double **x = atom->x; double **f = atom->f; int *type = atom->type; int nlocal = atom->nlocal; double *special_lj = force->special_lj; int newton_pair = force->newton_pair; double alphaOld12_ij, rmOld12_ij, epsilonOld12_ij; double alphaOld21_ij, rmOld21_ij, epsilonOld21_ij; double alpha12_ij, rm12_ij, epsilon12_ij; double alpha21_ij, rm21_ij, epsilon21_ij; double rminv, buck1, buck2; double epsilonOld1_i,alphaOld1_i,rmOld1_i; double epsilonOld1_j,alphaOld1_j,rmOld1_j; double epsilonOld2_i,alphaOld2_i,rmOld2_i; double epsilonOld2_j,alphaOld2_j,rmOld2_j; double epsilon1_i,alpha1_i,rm1_i; double epsilon1_j,alpha1_j,rm1_j; double epsilon2_i,alpha2_i,rm2_i; double epsilon2_j,alpha2_j,rm2_j; - double evdwlOldEXP6_12, evdwlOldEXP6_21; - double evdwlEXP6_12, evdwlEXP6_21, fpairEXP6_12, fpairEXP6_21; + double evdwlOldEXP6_12, evdwlOldEXP6_21, fpairOldEXP6_12, fpairOldEXP6_21; + double evdwlEXP6_12, evdwlEXP6_21; double fractionOld1_i, fractionOld1_j; double fractionOld2_i, fractionOld2_j; double fraction1_i, fraction1_j; double fraction2_i, fraction2_j; double *uCG = atom->uCG; double *uCGnew = atom->uCGnew; const int nRep = 12; const double shift = 1.05; double rin1, aRep, uin1, win1, uin1rep, rin1exp, rin6, rin6inv; // Initialize the Exp6 parameter data for both the local // and ghost atoms. Make the parameter data persistent // and exchange like any other atom property later. PairExp6ParamDataType PairExp6ParamData; { const int np_total = nlocal + atom->nghost; memory->create( PairExp6ParamData.epsilon1 , np_total, "PairExp6ParamData.epsilon1"); memory->create( PairExp6ParamData.alpha1 , np_total, "PairExp6ParamData.alpha1"); memory->create( PairExp6ParamData.rm1 , np_total, "PairExp6ParamData.rm1"); memory->create( PairExp6ParamData.fraction1 , np_total, "PairExp6ParamData.fraction1"); memory->create( PairExp6ParamData.epsilon2 , np_total, "PairExp6ParamData.epsilon2"); memory->create( PairExp6ParamData.alpha2 , np_total, "PairExp6ParamData.alpha2"); memory->create( PairExp6ParamData.rm2 , np_total, "PairExp6ParamData.rm2"); memory->create( PairExp6ParamData.fraction2 , np_total, "PairExp6ParamData.fraction2"); memory->create( PairExp6ParamData.epsilonOld1 , np_total, "PairExp6ParamData.epsilonOld1"); memory->create( PairExp6ParamData.alphaOld1 , np_total, "PairExp6ParamData.alphaOld1"); memory->create( PairExp6ParamData.rmOld1 , np_total, "PairExp6ParamData.rmOld1"); memory->create( PairExp6ParamData.fractionOld1 , np_total, "PairExp6ParamData.fractionOld1"); memory->create( PairExp6ParamData.epsilonOld2 , np_total, "PairExp6ParamData.epsilonOld2"); memory->create( PairExp6ParamData.alphaOld2 , np_total, "PairExp6ParamData.alphaOld2"); memory->create( PairExp6ParamData.rmOld2 , np_total, "PairExp6ParamData.rmOld2"); memory->create( PairExp6ParamData.fractionOld2 , np_total, "PairExp6ParamData.fractionOld2"); for (i = 0; i < np_total; ++i) { getParamsEXP6 (i, PairExp6ParamData.epsilon1[i], PairExp6ParamData.alpha1[i], PairExp6ParamData.rm1[i], PairExp6ParamData.fraction1[i], PairExp6ParamData.epsilon2[i], PairExp6ParamData.alpha2[i], PairExp6ParamData.rm2[i], PairExp6ParamData.fraction2[i], PairExp6ParamData.epsilonOld1[i], PairExp6ParamData.alphaOld1[i], PairExp6ParamData.rmOld1[i], PairExp6ParamData.fractionOld1[i], PairExp6ParamData.epsilonOld2[i], PairExp6ParamData.alphaOld2[i], PairExp6ParamData.rmOld2[i], PairExp6ParamData.fractionOld2[i]); } } inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; // loop over neighbors of my atoms for (ii = 0; ii < inum; ii++) { i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; jlist = firstneigh[i]; jnum = numneigh[i]; { epsilon1_i = PairExp6ParamData.epsilon1[i]; alpha1_i = PairExp6ParamData.alpha1[i]; rm1_i = PairExp6ParamData.rm1[i]; fraction1_i = PairExp6ParamData.fraction1[i]; epsilon2_i = PairExp6ParamData.epsilon2[i]; alpha2_i = PairExp6ParamData.alpha2[i]; rm2_i = PairExp6ParamData.rm2[i]; fraction2_i = PairExp6ParamData.fraction2[i]; epsilonOld1_i = PairExp6ParamData.epsilonOld1[i]; alphaOld1_i = PairExp6ParamData.alphaOld1[i]; rmOld1_i = PairExp6ParamData.rmOld1[i]; fractionOld1_i = PairExp6ParamData.fractionOld1[i]; epsilonOld2_i = PairExp6ParamData.epsilonOld2[i]; alphaOld2_i = PairExp6ParamData.alphaOld2[i]; rmOld2_i = PairExp6ParamData.rmOld2[i]; fractionOld2_i = PairExp6ParamData.fractionOld2[i]; } for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; factor_lj = special_lj[sbmask(j)]; j &= NEIGHMASK; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; rsq = delx*delx + dely*dely + delz*delz; jtype = type[j]; if (rsq < cutsq[itype][jtype]) { r2inv = 1.0/rsq; r6inv = r2inv*r2inv*r2inv; r = sqrt(rsq); rCut2inv = 1.0/cutsq[itype][jtype]; rCut6inv = rCut2inv*rCut2inv*rCut2inv; rCut = sqrt(cutsq[itype][jtype]); rCutInv = 1.0/rCut; // // A. Compute the exp-6 potential // // A1. Get alpha, epsilon and rm for particle j { epsilon1_j = PairExp6ParamData.epsilon1[j]; alpha1_j = PairExp6ParamData.alpha1[j]; rm1_j = PairExp6ParamData.rm1[j]; fraction1_j = PairExp6ParamData.fraction1[j]; epsilon2_j = PairExp6ParamData.epsilon2[j]; alpha2_j = PairExp6ParamData.alpha2[j]; rm2_j = PairExp6ParamData.rm2[j]; fraction2_j = PairExp6ParamData.fraction2[j]; epsilonOld1_j = PairExp6ParamData.epsilonOld1[j]; alphaOld1_j = PairExp6ParamData.alphaOld1[j]; rmOld1_j = PairExp6ParamData.rmOld1[j]; fractionOld1_j = PairExp6ParamData.fractionOld1[j]; epsilonOld2_j = PairExp6ParamData.epsilonOld2[j]; alphaOld2_j = PairExp6ParamData.alphaOld2[j]; rmOld2_j = PairExp6ParamData.rmOld2[j]; fractionOld2_j = PairExp6ParamData.fractionOld2[j]; } // A2. Apply Lorentz-Berthelot mixing rules for the i-j pair alphaOld12_ij = sqrt(alphaOld1_i*alphaOld2_j); rmOld12_ij = 0.5*(rmOld1_i + rmOld2_j); epsilonOld12_ij = sqrt(epsilonOld1_i*epsilonOld2_j); alphaOld21_ij = sqrt(alphaOld2_i*alphaOld1_j); rmOld21_ij = 0.5*(rmOld2_i + rmOld1_j); epsilonOld21_ij = sqrt(epsilonOld2_i*epsilonOld1_j); alpha12_ij = sqrt(alpha1_i*alpha2_j); rm12_ij = 0.5*(rm1_i + rm2_j); epsilon12_ij = sqrt(epsilon1_i*epsilon2_j); alpha21_ij = sqrt(alpha2_i*alpha1_j); rm21_ij = 0.5*(rm2_i + rm1_j); epsilon21_ij = sqrt(epsilon2_i*epsilon1_j); if(rmOld12_ij!=0.0 && rmOld21_ij!=0.0){ if(alphaOld21_ij == 6.0 || alphaOld12_ij == 6.0) error->all(FLERR,"alpha_ij is 6.0 in pair exp6"); // A3. Compute some convenient quantities for evaluating the force rminv = 1.0/rmOld12_ij; buck1 = epsilonOld12_ij / (alphaOld12_ij - 6.0); rexp = expValue(alphaOld12_ij*(1.0-r*rminv)); rm2ij = rmOld12_ij*rmOld12_ij; rm6ij = rm2ij*rm2ij*rm2ij; // Compute the shifted potential rCutExp = expValue(alphaOld12_ij*(1.0-rCut*rminv)); buck2 = 6.0*alphaOld12_ij; urc = buck1*(6.0*rCutExp - alphaOld12_ij*rm6ij*rCut6inv); durc = -buck1*buck2*(rCutExp* rminv - rCutInv*rm6ij*rCut6inv); rin1 = shift*rmOld12_ij*func_rin(alphaOld12_ij); if(r < rin1){ rin6 = rin1*rin1*rin1*rin1*rin1*rin1; rin6inv = 1.0/rin6; rin1exp = expValue(alphaOld12_ij*(1.0-rin1*rminv)); uin1 = buck1*(6.0*rin1exp - alphaOld12_ij*rm6ij*rin6inv) - urc - durc*(rin1-rCut); - win1 = buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) - rin1*durc; + win1 = -buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) - rin1*durc; aRep = -1.0*win1*powint(rin1,nRep)/nRep; uin1rep = aRep/powint(rin1,nRep); - evdwlOldEXP6_12 = uin1 - uin1rep + aRep/powint(r,nRep); + forceExp6 = -double(nRep)*aRep/powint(r,nRep); + fpairOldEXP6_12 = factor_lj*forceExp6*r2inv; + evdwlOldEXP6_12 = uin1 - uin1rep + aRep/powint(r,nRep); } else { + forceExp6 = buck1*buck2*(r*rexp*rminv - rm6ij*r6inv) + r*durc; + fpairOldEXP6_12 = factor_lj*forceExp6*r2inv; + evdwlOldEXP6_12 = buck1*(6.0*rexp - alphaOld12_ij*rm6ij*r6inv) - urc - durc*(r-rCut); } // A3. Compute some convenient quantities for evaluating the force rminv = 1.0/rmOld21_ij; buck1 = epsilonOld21_ij / (alphaOld21_ij - 6.0); buck2 = 6.0*alphaOld21_ij; rexp = expValue(alphaOld21_ij*(1.0-r*rminv)); rm2ij = rmOld21_ij*rmOld21_ij; rm6ij = rm2ij*rm2ij*rm2ij; // Compute the shifted potential rCutExp = expValue(alphaOld21_ij*(1.0-rCut*rminv)); buck2 = 6.0*alphaOld21_ij; urc = buck1*(6.0*rCutExp - alphaOld21_ij*rm6ij*rCut6inv); durc = -buck1*buck2*(rCutExp* rminv - rCutInv*rm6ij*rCut6inv); rin1 = shift*rmOld21_ij*func_rin(alphaOld21_ij); if(r < rin1){ rin6 = rin1*rin1*rin1*rin1*rin1*rin1; rin6inv = 1.0/rin6; rin1exp = expValue(alphaOld21_ij*(1.0-rin1*rminv)); uin1 = buck1*(6.0*rin1exp - alphaOld21_ij*rm6ij*rin6inv) - urc - durc*(rin1-rCut); - win1 = buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) - rin1*durc; + win1 = -buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) - rin1*durc; aRep = -1.0*win1*powint(rin1,nRep)/nRep; uin1rep = aRep/powint(rin1,nRep); - evdwlOldEXP6_21 = uin1 - uin1rep + aRep/powint(r,nRep); + forceExp6 = -double(nRep)*aRep/powint(r,nRep); + fpairOldEXP6_21 = factor_lj*forceExp6*r2inv; + evdwlOldEXP6_21 = uin1 - uin1rep + aRep/powint(r,nRep); } else { + forceExp6 = buck1*buck2*(r*rexp*rminv - rm6ij*r6inv) + r*durc; + fpairOldEXP6_21 = factor_lj*forceExp6*r2inv; + evdwlOldEXP6_21 = buck1*(6.0*rexp - alphaOld21_ij*rm6ij*r6inv) - urc - durc*(r-rCut); } if (isite1 == isite2) evdwlOld = sqrt(fractionOld1_i*fractionOld2_j)*evdwlOldEXP6_12; else evdwlOld = sqrt(fractionOld1_i*fractionOld2_j)*evdwlOldEXP6_12 + sqrt(fractionOld2_i*fractionOld1_j)*evdwlOldEXP6_21; evdwlOld *= factor_lj; uCG[i] += 0.5*evdwlOld; if (newton_pair || j < nlocal) uCG[j] += 0.5*evdwlOld; } if(rm12_ij!=0.0 && rm21_ij!=0.0){ if(alpha21_ij == 6.0 || alpha12_ij == 6.0) error->all(FLERR,"alpha_ij is 6.0 in pair exp6"); // A3. Compute some convenient quantities for evaluating the force rminv = 1.0/rm12_ij; buck1 = epsilon12_ij / (alpha12_ij - 6.0); buck2 = 6.0*alpha12_ij; rexp = expValue(alpha12_ij*(1.0-r*rminv)); rm2ij = rm12_ij*rm12_ij; rm6ij = rm2ij*rm2ij*rm2ij; // Compute the shifted potential rCutExp = expValue(alpha12_ij*(1.0-rCut*rminv)); urc = buck1*(6.0*rCutExp - alpha12_ij*rm6ij*rCut6inv); durc = -buck1*buck2*(rCutExp*rminv - rCutInv*rm6ij*rCut6inv); rin1 = shift*rm12_ij*func_rin(alpha12_ij); if(r < rin1){ rin6 = rin1*rin1*rin1*rin1*rin1*rin1; rin6inv = 1.0/rin6; rin1exp = expValue(alpha12_ij*(1.0-rin1*rminv)); uin1 = buck1*(6.0*rin1exp - alpha12_ij*rm6ij*rin6inv) - urc - durc*(rin1-rCut); - win1 = buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) - rin1*durc; + win1 = -buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) - rin1*durc; aRep = -1.0*win1*powint(rin1,nRep)/nRep; uin1rep = aRep/powint(rin1,nRep); evdwlEXP6_12 = uin1 - uin1rep + aRep/powint(r,nRep); - - forceExp6 = -double(nRep)*aRep/powint(r,nRep); - fpairEXP6_12 = factor_lj*forceExp6*r2inv; - } else { - - // A4. Compute the exp-6 force and energy - forceExp6 = buck1*buck2*(r*rexp*rminv - rm6ij*r6inv) + r*durc; - fpairEXP6_12 = factor_lj*forceExp6*r2inv; evdwlEXP6_12 = buck1*(6.0*rexp - alpha12_ij*rm6ij*r6inv) - urc - durc*(r-rCut); } rminv = 1.0/rm21_ij; buck1 = epsilon21_ij / (alpha21_ij - 6.0); buck2 = 6.0*alpha21_ij; rexp = expValue(alpha21_ij*(1.0-r*rminv)); rm2ij = rm21_ij*rm21_ij; rm6ij = rm2ij*rm2ij*rm2ij; // Compute the shifted potential rCutExp = expValue(alpha21_ij*(1.0-rCut*rminv)); urc = buck1*(6.0*rCutExp - alpha21_ij*rm6ij*rCut6inv); durc = -buck1*buck2*(rCutExp*rminv - rCutInv*rm6ij*rCut6inv); rin1 = shift*rm21_ij*func_rin(alpha21_ij); if(r < rin1){ rin6 = rin1*rin1*rin1*rin1*rin1*rin1; rin6inv = 1.0/rin6; rin1exp = expValue(alpha21_ij*(1.0-rin1*rminv)); uin1 = buck1*(6.0*rin1exp - alpha21_ij*rm6ij*rin6inv) - urc - durc*(rin1-rCut); - win1 = buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) - rin1*durc; + win1 = -buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) - rin1*durc; aRep = -1.0*win1*powint(rin1,nRep)/nRep; uin1rep = aRep/powint(rin1,nRep); evdwlEXP6_21 = uin1 - uin1rep + aRep/powint(r,nRep); - - forceExp6 = -double(nRep)*aRep/powint(r,nRep); - fpairEXP6_21 = factor_lj*forceExp6*r2inv; - } else { - - // A4. Compute the exp-6 force and energy - forceExp6 = buck1*buck2*(r*rexp*rminv - rm6ij*r6inv) + r*durc; - fpairEXP6_21 = factor_lj*forceExp6*r2inv; evdwlEXP6_21 = buck1*(6.0*rexp - alpha21_ij*rm6ij*r6inv) - urc - durc*(r-rCut); } // // Apply Mixing Rule to get the overall force for the CG pair // - if (isite1 == isite2) fpair = sqrt(fractionOld1_i*fractionOld2_j)*fpairEXP6_12; - else fpair = sqrt(fractionOld1_i*fractionOld2_j)*fpairEXP6_12 + sqrt(fractionOld2_i*fractionOld1_j)*fpairEXP6_21; + if (isite1 == isite2) fpair = sqrt(fractionOld1_i*fractionOld2_j)*fpairOldEXP6_12; + else fpair = sqrt(fractionOld1_i*fractionOld2_j)*fpairOldEXP6_12 + sqrt(fractionOld2_i*fractionOld1_j)*fpairOldEXP6_21; f[i][0] += delx*fpair; f[i][1] += dely*fpair; f[i][2] += delz*fpair; if (newton_pair || j < nlocal) { f[j][0] -= delx*fpair; f[j][1] -= dely*fpair; f[j][2] -= delz*fpair; } if (isite1 == isite2) evdwl = sqrt(fraction1_i*fraction2_j)*evdwlEXP6_12; else evdwl = sqrt(fraction1_i*fraction2_j)*evdwlEXP6_12 + sqrt(fraction2_i*fraction1_j)*evdwlEXP6_21; evdwl *= factor_lj; uCGnew[i] += 0.5*evdwl; if (newton_pair || j < nlocal) uCGnew[j] += 0.5*evdwl; evdwl = evdwlOld; if (evflag) ev_tally(i,j,nlocal,newton_pair, evdwl,0.0,fpair,delx,dely,delz); } } } } if (vflag_fdotr) virial_fdotr_compute(); // Release the local parameter data. { if (PairExp6ParamData.epsilon1 ) memory->destroy(PairExp6ParamData.epsilon1); if (PairExp6ParamData.alpha1 ) memory->destroy(PairExp6ParamData.alpha1); if (PairExp6ParamData.rm1 ) memory->destroy(PairExp6ParamData.rm1); if (PairExp6ParamData.fraction1 ) memory->destroy(PairExp6ParamData.fraction1); if (PairExp6ParamData.epsilon2 ) memory->destroy(PairExp6ParamData.epsilon2); if (PairExp6ParamData.alpha2 ) memory->destroy(PairExp6ParamData.alpha2); if (PairExp6ParamData.rm2 ) memory->destroy(PairExp6ParamData.rm2); if (PairExp6ParamData.fraction2 ) memory->destroy(PairExp6ParamData.fraction2); if (PairExp6ParamData.epsilonOld1 ) memory->destroy(PairExp6ParamData.epsilonOld1); if (PairExp6ParamData.alphaOld1 ) memory->destroy(PairExp6ParamData.alphaOld1); if (PairExp6ParamData.rmOld1 ) memory->destroy(PairExp6ParamData.rmOld1); if (PairExp6ParamData.fractionOld1) memory->destroy(PairExp6ParamData.fractionOld1); if (PairExp6ParamData.epsilonOld2 ) memory->destroy(PairExp6ParamData.epsilonOld2); if (PairExp6ParamData.alphaOld2 ) memory->destroy(PairExp6ParamData.alphaOld2); if (PairExp6ParamData.rmOld2 ) memory->destroy(PairExp6ParamData.rmOld2); if (PairExp6ParamData.fractionOld2) memory->destroy(PairExp6ParamData.fractionOld2); } } /* ---------------------------------------------------------------------- allocate all arrays ------------------------------------------------------------------------- */ void PairExp6rx::allocate() { allocated = 1; int n = atom->ntypes; memory->create(setflag,n+1,n+1,"pair:setflag"); for (int i = 1; i <= n; i++) for (int j = i; j <= n; j++) setflag[i][j] = 0; memory->create(cutsq,n+1,n+1,"pair:cutsq"); memory->create(cut,n+1,n+1,"pair:cut_lj"); } /* ---------------------------------------------------------------------- global settings ------------------------------------------------------------------------- */ void PairExp6rx::settings(int narg, char **arg) { if (narg != 1) error->all(FLERR,"Illegal pair_style command"); cut_global = force->numeric(FLERR,arg[0]); if (allocated) { int i,j; for (i = 1; i <= atom->ntypes; i++) for (j = i+1; j <= atom->ntypes; j++) if (setflag[i][j]) cut[i][j] = cut_global; } allocated = 0; } /* ---------------------------------------------------------------------- set coeffs for one or more type pairs ------------------------------------------------------------------------- */ void PairExp6rx::coeff(int narg, char **arg) { if (narg < 7 || narg > 8) error->all(FLERR,"Incorrect args for pair coefficients"); bool rx_flag = false; for (int i = 0; i < modify->nfix; i++) if (strncmp(modify->fix[i]->style,"rx",2) == 0) rx_flag = true; if (!rx_flag) error->all(FLERR,"PairExp6rx requires a fix rx command."); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; int n; force->bounds(arg[0],atom->ntypes,ilo,ihi); force->bounds(arg[1],atom->ntypes,jlo,jhi); nspecies = atom->nspecies_dpd; if(nspecies==0) error->all(FLERR,"There are no rx species specified."); read_file(arg[2]); n = strlen(arg[3]) + 1; site1 = new char[n]; strcpy(site1,arg[3]); int ispecies; for (ispecies = 0; ispecies < nspecies; ispecies++){ if (strcmp(site1,&atom->dname[ispecies][0]) == 0) break; } if (ispecies == nspecies && strcmp(site1,"1fluid") != 0) error->all(FLERR,"Site1 name not recognized in pair coefficients"); n = strlen(arg[4]) + 1; site2 = new char[n]; strcpy(site2,arg[4]); for (ispecies = 0; ispecies < nspecies; ispecies++){ if (strcmp(site2,&atom->dname[ispecies][0]) == 0) break; } if (ispecies == nspecies && strcmp(site2,"1fluid") != 0) error->all(FLERR,"Site2 name not recognized in pair coefficients"); { // Set isite1 and isite2 parameters based on site1 and site2 strings. if (strcmp(site1,"1fluid") == 0) isite1 = oneFluidApproxParameter; else { int isp; for (isp = 0; isp < nspecies; isp++) if (strcmp(site1, &atom->dname[isp][0]) == 0) break; if (isp == nspecies) error->all(FLERR,"Site1 name not recognized in pair coefficients"); else isite1 = isp; } if (strcmp(site2,"1fluid") == 0) isite2 = oneFluidApproxParameter; else { int isp; for (isp = 0; isp < nspecies; isp++) if (strcmp(site2, &atom->dname[isp][0]) == 0) break; if (isp == nspecies) error->all(FLERR,"Site2 name not recognized in pair coefficients"); else isite2 = isp; } // Set the interaction potential type to the enumerated type. for (int iparam = 0; iparam < nparams; ++iparam) { if (strcmp( params[iparam].potential, "exp6") == 0) params[iparam].potentialType = exp6PotentialType; else error->all(FLERR,"params[].potential type unknown"); //printf("params[%d].name= %s ispecies= %d potential= %s potentialType= %d\n", iparam, params[iparam].name, params[iparam].ispecies, params[iparam].potential, params[iparam].potentialType); } } delete[] site1; delete[] site2; site1 = site2 = NULL; fuchslinR = force->numeric(FLERR,arg[5]); fuchslinEpsilon = force->numeric(FLERR,arg[6]); setup(); double cut_one = cut_global; if (narg == 8) cut_one = force->numeric(FLERR,arg[7]); int count = 0; for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { cut[i][j] = cut_one; setflag[i][j] = 1; count++; } } if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ double PairExp6rx::init_one(int i, int j) { if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); return cut[i][j]; } /* ---------------------------------------------------------------------- */ void PairExp6rx::read_file(char *file) { int params_per_line = 5; char **words = new char*[params_per_line+1]; memory->sfree(params); params = NULL; nparams = maxparam = 0; // open file on proc 0 FILE *fp; fp = NULL; if (comm->me == 0) { fp = force->open_potential(file); if (fp == NULL) { char str[128]; sprintf(str,"Cannot open exp6/rx potential file %s",file); error->one(FLERR,str); } } // read each set of params from potential file // one set of params can span multiple lines int n,nwords,ispecies; char line[MAXLINE],*ptr; int eof = 0; while (1) { if (comm->me == 0) { ptr = fgets(line,MAXLINE,fp); if (ptr == NULL) { eof = 1; fclose(fp); } else n = strlen(line) + 1; } MPI_Bcast(&eof,1,MPI_INT,0,world); if (eof) break; MPI_Bcast(&n,1,MPI_INT,0,world); MPI_Bcast(line,n,MPI_CHAR,0,world); // strip comment, skip line if blank if ((ptr = strchr(line,'#'))) *ptr = '\0'; nwords = atom->count_words(line); if (nwords == 0) continue; // concatenate additional lines until have params_per_line words while (nwords < params_per_line) { n = strlen(line); if (comm->me == 0) { ptr = fgets(&line[n],MAXLINE-n,fp); if (ptr == NULL) { eof = 1; fclose(fp); } else n = strlen(line) + 1; } MPI_Bcast(&eof,1,MPI_INT,0,world); if (eof) break; MPI_Bcast(&n,1,MPI_INT,0,world); MPI_Bcast(line,n,MPI_CHAR,0,world); if ((ptr = strchr(line,'#'))) *ptr = '\0'; nwords = atom->count_words(line); } if (nwords != params_per_line) error->all(FLERR,"Incorrect format in exp6/rx potential file"); // words = ptrs to all words in line nwords = 0; words[nwords++] = strtok(line," \t\n\r\f"); while ((words[nwords++] = strtok(NULL," \t\n\r\f"))) continue; for (ispecies = 0; ispecies < nspecies; ispecies++) if (strcmp(words[0],&atom->dname[ispecies][0]) == 0) break; if (ispecies == nspecies) continue; // load up parameter settings and error check their values if (nparams == maxparam) { maxparam += DELTA; params = (Param *) memory->srealloc(params,maxparam*sizeof(Param), "pair:params"); } params[nparams].ispecies = ispecies; n = strlen(&atom->dname[ispecies][0]) + 1; params[nparams].name = new char[n]; strcpy(params[nparams].name,&atom->dname[ispecies][0]); n = strlen(words[1]) + 1; params[nparams].potential = new char[n]; strcpy(params[nparams].potential,words[1]); if (strcmp(params[nparams].potential,"exp6") == 0){ params[nparams].alpha = atof(words[2]); params[nparams].epsilon = atof(words[3]); params[nparams].rm = atof(words[4]); if (params[nparams].epsilon <= 0.0 || params[nparams].rm <= 0.0 || params[nparams].alpha < 0.0) error->all(FLERR,"Illegal exp6/rx parameters. Rm and Epsilon must be greater than zero. Alpha cannot be negative."); } else { error->all(FLERR,"Illegal exp6/rx parameters. Interaction potential does not exist."); } nparams++; } delete [] words; } /* ---------------------------------------------------------------------- */ void PairExp6rx::setup() { int i,j,n; // set mol2param for all combinations // must be a single exact match to lines read from file memory->destroy(mol2param); memory->create(mol2param,nspecies,"pair:mol2param"); for (i = 0; i < nspecies; i++) { n = -1; for (j = 0; j < nparams; j++) { if (i == params[j].ispecies) { if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); n = j; } } mol2param[i] = n; } } /* ---------------------------------------------------------------------- proc 0 writes to restart file ------------------------------------------------------------------------- */ void PairExp6rx::write_restart(FILE *fp) { write_restart_settings(fp); int i,j; for (i = 1; i <= atom->ntypes; i++) for (j = i; j <= atom->ntypes; j++) { fwrite(&setflag[i][j],sizeof(int),1,fp); if (setflag[i][j]) { fwrite(&cut[i][j],sizeof(double),1,fp); } } } /* ---------------------------------------------------------------------- proc 0 reads from restart file, bcasts ------------------------------------------------------------------------- */ void PairExp6rx::read_restart(FILE *fp) { read_restart_settings(fp); allocate(); int i,j; int me = comm->me; for (i = 1; i <= atom->ntypes; i++) for (j = i; j <= atom->ntypes; j++) { if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp); MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world); if (setflag[i][j]) { if (me == 0) { fread(&cut[i][j],sizeof(double),1,fp); } MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); } } } /* ---------------------------------------------------------------------- proc 0 writes to restart file ------------------------------------------------------------------------- */ void PairExp6rx::write_restart_settings(FILE *fp) { fwrite(&cut_global,sizeof(double),1,fp); fwrite(&offset_flag,sizeof(int),1,fp); fwrite(&mix_flag,sizeof(int),1,fp); fwrite(&tail_flag,sizeof(int),1,fp); } /* ---------------------------------------------------------------------- proc 0 reads from restart file, bcasts ------------------------------------------------------------------------- */ void PairExp6rx::read_restart_settings(FILE *fp) { if (comm->me == 0) { fread(&cut_global,sizeof(double),1,fp); fread(&offset_flag,sizeof(int),1,fp); fread(&mix_flag,sizeof(int),1,fp); fread(&tail_flag,sizeof(int),1,fp); } MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world); MPI_Bcast(&offset_flag,1,MPI_INT,0,world); MPI_Bcast(&mix_flag,1,MPI_INT,0,world); MPI_Bcast(&tail_flag,1,MPI_INT,0,world); } /* ---------------------------------------------------------------------- */ void PairExp6rx::getParamsEXP6(int id,double &epsilon1,double &alpha1,double &rm1, double &fraction1,double &epsilon2,double &alpha2,double &rm2,double &fraction2,double &epsilon1_old,double &alpha1_old,double &rm1_old, double &fraction1_old,double &epsilon2_old,double &alpha2_old,double &rm2_old,double &fraction2_old) const { int iparam, jparam; double rmi, rmj, rmij, rm3ij; double epsiloni, epsilonj, epsilonij; double alphai, alphaj, alphaij; double epsilon_old, rm3_old, alpha_old; double epsilon, rm3, alpha; double fractionOFA, fractionOFA_old; double nTotalOFA, nTotalOFA_old; double nTotal, nTotal_old; double xMolei, xMolej, xMolei_old, xMolej_old; rm3 = 0.0; epsilon = 0.0; alpha = 0.0; epsilon_old = 0.0; rm3_old = 0.0; alpha_old = 0.0; fractionOFA = 0.0; fractionOFA_old = 0.0; nTotalOFA = 0.0; nTotalOFA_old = 0.0; nTotal = 0.0; nTotal_old = 0.0; // Compute the total number of molecules in the old and new CG particle as well as the total number of molecules in the fluid portion of the old and new CG particle for (int ispecies = 0; ispecies < nspecies; ispecies++){ nTotal += atom->dvector[ispecies][id]; nTotal_old += atom->dvector[ispecies+nspecies][id]; iparam = mol2param[ispecies]; if (iparam < 0 || params[iparam].potentialType != exp6PotentialType ) continue; if (isOneFluidApprox(isite1) || isOneFluidApprox(isite2)) { if (isite1 == params[iparam].ispecies || isite2 == params[iparam].ispecies) continue; nTotalOFA_old += atom->dvector[ispecies+nspecies][id]; nTotalOFA += atom->dvector[ispecies][id]; } } if(nTotal < 1e-8 || nTotal_old < 1e-8) error->all(FLERR,"The number of molecules in CG particle is less than 1e-8."); // Compute the mole fraction of molecules within the fluid portion of the particle (One Fluid Approximation) fractionOFA_old = nTotalOFA_old / nTotal_old; fractionOFA = nTotalOFA / nTotal; for (int ispecies = 0; ispecies < nspecies; ispecies++) { iparam = mol2param[ispecies]; if (iparam < 0 || params[iparam].potentialType != exp6PotentialType ) continue; // If Site1 matches a pure species, then grab the parameters if (isite1 == params[iparam].ispecies){ rm1_old = params[iparam].rm; rm1 = params[iparam].rm; epsilon1_old = params[iparam].epsilon; epsilon1 = params[iparam].epsilon; alpha1_old = params[iparam].alpha; alpha1 = params[iparam].alpha; // Compute the mole fraction of Site1 fraction1_old = atom->dvector[ispecies+nspecies][id]/nTotal_old; fraction1 = atom->dvector[ispecies][id]/nTotal; } // If Site2 matches a pure species, then grab the parameters if (isite2 == params[iparam].ispecies){ rm2_old = params[iparam].rm; rm2 = params[iparam].rm; epsilon2_old = params[iparam].epsilon; epsilon2 = params[iparam].epsilon; alpha2_old = params[iparam].alpha; alpha2 = params[iparam].alpha; // Compute the mole fraction of Site2 fraction2_old = atom->dvector[ispecies+nspecies][id]/nTotal_old; fraction2 = atom->dvector[ispecies][id]/nTotal; } // If Site1 or Site2 matches is a fluid, then compute the paramters if (isOneFluidApprox(isite1) || isOneFluidApprox(isite2)) { if (isite1 == params[iparam].ispecies || isite2 == params[iparam].ispecies) continue; rmi = params[iparam].rm; epsiloni = params[iparam].epsilon; alphai = params[iparam].alpha; xMolei = atom->dvector[ispecies][id]/nTotalOFA; xMolei_old = atom->dvector[ispecies+nspecies][id]/nTotalOFA_old; for (int jspecies = 0; jspecies < nspecies; jspecies++) { jparam = mol2param[jspecies]; if (jparam < 0 || params[jparam].potentialType != exp6PotentialType ) continue; if (isite1 == params[jparam].ispecies || isite2 == params[jparam].ispecies) continue; rmj = params[jparam].rm; epsilonj = params[jparam].epsilon; alphaj = params[jparam].alpha; xMolej = atom->dvector[jspecies][id]/nTotalOFA; xMolej_old = atom->dvector[jspecies+nspecies][id]/nTotalOFA_old; rmij = (rmi+rmj)/2.0; rm3ij = rmij*rmij*rmij; epsilonij = sqrt(epsiloni*epsilonj); alphaij = sqrt(alphai*alphaj); if(fractionOFA_old > 0.0){ rm3_old += xMolei_old*xMolej_old*rm3ij; epsilon_old += xMolei_old*xMolej_old*rm3ij*epsilonij; alpha_old += xMolei_old*xMolej_old*rm3ij*epsilonij*alphaij; } if(fractionOFA > 0.0){ rm3 += xMolei*xMolej*rm3ij; epsilon += xMolei*xMolej*rm3ij*epsilonij; alpha += xMolei*xMolej*rm3ij*epsilonij*alphaij; } } } } if (isOneFluidApprox(isite1)){ rm1 = cbrt(rm3); if(rm1 < 1e-16) { rm1 = 0.0; epsilon1 = 0.0; alpha1 = 0.0; } else { epsilon1 = epsilon / rm3; alpha1 = alpha / epsilon1 / rm3; } fraction1 = fractionOFA; rm1_old = cbrt(rm3_old); if(rm1_old < 1e-16) { rm1_old = 0.0; epsilon1_old = 0.0; alpha1_old = 0.0; } else { epsilon1_old = epsilon_old / rm3_old; alpha1_old = alpha_old / epsilon1_old / rm3_old; } fraction1_old = fractionOFA_old; // Fuchslin-Like Exp-6 Scaling double powfuch = 0.0; if(fuchslinEpsilon < 0.0){ powfuch = pow(nTotalOFA,-fuchslinEpsilon); if(powfuch<1e-15) epsilon1 = 0.0; else epsilon1 *= 1.0/powfuch; powfuch = pow(nTotalOFA_old,-fuchslinEpsilon); if(powfuch<1e-15) epsilon1_old = 0.0; else epsilon1_old *= 1.0/powfuch; } else { epsilon1 *= pow(nTotalOFA,fuchslinEpsilon); epsilon1_old *= pow(nTotalOFA_old,fuchslinEpsilon); } if(fuchslinR < 0.0){ powfuch = pow(nTotalOFA,-fuchslinR); if(powfuch<1e-15) rm1 = 0.0; else rm1 *= 1.0/powfuch; powfuch = pow(nTotalOFA_old,-fuchslinR); if(powfuch<1e-15) rm1_old = 0.0; else rm1_old *= 1.0/powfuch; } else { rm1 *= pow(nTotalOFA,fuchslinR); rm1_old *= pow(nTotalOFA_old,fuchslinR); } } if (isOneFluidApprox(isite2)){ rm2 = cbrt(rm3); if(rm2 < 1e-16) { rm2 = 0.0; epsilon2 = 0.0; alpha2 = 0.0; } else { epsilon2 = epsilon / rm3; alpha2 = alpha / epsilon2 / rm3; } fraction2 = fractionOFA; rm2_old = cbrt(rm3_old); if(rm2_old < 1e-16) { rm2_old = 0.0; epsilon2_old = 0.0; alpha2_old = 0.0; } else { epsilon2_old = epsilon_old / rm3_old; alpha2_old = alpha_old / epsilon2_old / rm3_old; } fraction2_old = fractionOFA_old; // Fuchslin-Like Exp-6 Scaling double powfuch = 0.0; if(fuchslinEpsilon < 0.0){ powfuch = pow(nTotalOFA,-fuchslinEpsilon); if(powfuch<1e-15) epsilon2 = 0.0; else epsilon2 *= 1.0/powfuch; powfuch = pow(nTotalOFA_old,-fuchslinEpsilon); if(powfuch<1e-15) epsilon2_old = 0.0; else epsilon2_old *= 1.0/powfuch; } else { epsilon2 *= pow(nTotalOFA,fuchslinEpsilon); epsilon2_old *= pow(nTotalOFA_old,fuchslinEpsilon); } if(fuchslinR < 0.0){ powfuch = pow(nTotalOFA,-fuchslinR); if(powfuch<1e-15) rm2 = 0.0; else rm2 *= 1.0/powfuch; powfuch = pow(nTotalOFA_old,-fuchslinR); if(powfuch<1e-15) rm2_old = 0.0; else rm2_old *= 1.0/powfuch; } else { rm2 *= pow(nTotalOFA,fuchslinR); rm2_old *= pow(nTotalOFA_old,fuchslinR); } } } /* ---------------------------------------------------------------------- */ inline double PairExp6rx::func_rin(const double &alpha) const { double function; const double a = 3.7682065; const double b = -1.4308614; function = a+b*sqrt(alpha); function = expValue(function); return function; } /* ---------------------------------------------------------------------- */ inline double PairExp6rx::expValue(double value) const { double returnValue; if(value < DBL_MIN_EXP) returnValue = 0.0; else returnValue = exp(value); return returnValue; } diff --git a/src/USER-DPD/pair_multi_lucy.cpp b/src/USER-DPD/pair_multi_lucy.cpp index 501ef2d04..a063eff19 100644 --- a/src/USER-DPD/pair_multi_lucy.cpp +++ b/src/USER-DPD/pair_multi_lucy.cpp @@ -1,833 +1,833 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------- Contributing authors: James Larentzos and Joshua Moore (U.S. Army Research Laboratory) Please cite the related publications: J.D. Moore, B.C. Barnes, S. Izvekov, M. Lisal, M.S. Sellers, D.E. Taylor & J.K. Brennan "A coarse-grain force field for RDX: Density dependent and energy conserving" The Journal of Chemical Physics, 2016, 144, 104501. ------------------------------------------------------------------------------------------- */ -#include "mpi.h" +#include #include #include "math_const.h" #include #include #include "pair_multi_lucy.h" #include "atom.h" #include "force.h" #include "comm.h" #include "neigh_list.h" #include "memory.h" #include "error.h" #include "citeme.h" using namespace LAMMPS_NS; enum{NONE,RLINEAR,RSQ}; #define MAXLINE 1024 static const char cite_pair_multi_lucy[] = "pair_style multi/lucy command:\n\n" "@Article{Moore16,\n" " author = {J.D. Moore, B.C. Barnes, S. Izvekov, M. Lisal, M.S. Sellers, D.E. Taylor and J. K. Brennan},\n" " title = {A coarse-grain force field for RDX: Density dependent and energy conserving},\n" " journal = {J. Chem. Phys.},\n" " year = 2016,\n" " volume = 144\n" " pages = {104501}\n" "}\n\n"; /* ---------------------------------------------------------------------- */ PairMultiLucy::PairMultiLucy(LAMMPS *lmp) : Pair(lmp) { if (lmp->citeme) lmp->citeme->add(cite_pair_multi_lucy); if (atom->rho_flag != 1) error->all(FLERR,"Pair multi/lucy command requires atom_style with density (e.g. dpd, meso)"); ntables = 0; tables = NULL; comm_forward = 1; comm_reverse = 1; } /* ---------------------------------------------------------------------- */ PairMultiLucy::~PairMultiLucy() { for (int m = 0; m < ntables; m++) free_table(&tables[m]); memory->sfree(tables); if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); memory->destroy(tabindex); } } /* ---------------------------------------------------------------------- */ void PairMultiLucy::compute(int eflag, int vflag) { int i,j,ii,jj,inum,jnum,itype,jtype,itable; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair,rsq; int *ilist,*jlist,*numneigh,**firstneigh; Table *tb; int tlm1 = tablength - 1; evdwl = 0.0; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; double **x = atom->x; double **f = atom->f; int *type = atom->type; int nlocal = atom->nlocal; int newton_pair = force->newton_pair; double pi = MathConst::MY_PI; double A_i; double A_j; double fraction_i,fraction_j; int jtable; double *rho = atom->rho; inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; computeLocalDensity(); // loop over neighbors of my atoms for (ii = 0; ii < inum; ii++) { i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; jlist = firstneigh[i]; jnum = numneigh[i]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; j &= NEIGHMASK; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; rsq = delx*delx + dely*dely + delz*delz; jtype = type[j]; if (rsq < cutsq[itype][jtype]) { tb = &tables[tabindex[itype][jtype]]; if (rho[i]*rho[i] < tb->innersq || rho[j]*rho[j] < tb->innersq) error->one(FLERR,"Density < table inner cutoff"); if (tabstyle == LOOKUP) { itable = static_cast (((rho[i]*rho[i]) - tb->innersq) * tb->invdelta); jtable = static_cast (((rho[j]*rho[j]) - tb->innersq) * tb->invdelta); if (itable >= tlm1 || jtable >= tlm1) error->one(FLERR,"Density > table outer cutoff"); A_i = tb->f[itable]; A_j = tb->f[jtable]; fpair = 0.5*(A_i + A_j)*(1.0+3.0*sqrt(rsq)/sqrt(cutsq[itype][jtype]))*(1.0 - sqrt(rsq)/sqrt(cutsq[itype][jtype]))*(1.0 - sqrt(rsq)/sqrt(cutsq[itype][jtype]))*(1.0 - sqrt(rsq)/sqrt(cutsq[itype][jtype])); fpair = fpair/sqrt(rsq); } else if (tabstyle == LINEAR) { itable = static_cast ((rho[i]*rho[i] - tb->innersq) * tb->invdelta); jtable = static_cast (((rho[j]*rho[j]) - tb->innersq) * tb->invdelta); if (itable >= tlm1 || jtable >= tlm1) error->one(FLERR,"Density > table outer cutoff"); fraction_i = (((rho[i]*rho[i]) - tb->rsq[itable]) * tb->invdelta); fraction_j = (((rho[j]*rho[j]) - tb->rsq[jtable]) * tb->invdelta); A_i = tb->f[itable] + fraction_i*tb->df[itable]; A_j = tb->f[jtable] + fraction_j*tb->df[jtable]; fpair = 0.5*(A_i + A_j)*(1.0+3.0*sqrt(rsq)/sqrt(cutsq[itype][jtype]))*(1.0 - sqrt(rsq)/sqrt(cutsq[itype][jtype]))*(1.0 - sqrt(rsq)/sqrt(cutsq[itype][jtype]))*(1.0 - sqrt(rsq)/sqrt(cutsq[itype][jtype])); fpair = fpair / sqrt(rsq); } else error->one(FLERR,"Only LOOKUP and LINEAR table styles have been implemented for pair multi/lucy"); f[i][0] += delx*fpair; f[i][1] += dely*fpair; f[i][2] += delz*fpair; if (newton_pair || j < nlocal) { f[j][0] -= delx*fpair; f[j][1] -= dely*fpair; f[j][2] -= delz*fpair; } if (evflag) ev_tally(i,j,nlocal,newton_pair, 0.0,0.0,fpair,delx,dely,delz); } } tb = &tables[tabindex[itype][itype]]; if (rho[i]*rho[i] < tb->innersq || rho[j]*rho[j] < tb->innersq) error->one(FLERR,"Density < table inner cutoff"); itable = static_cast (((rho[i]*rho[i]) - tb->innersq) * tb->invdelta); if (tabstyle == LOOKUP) evdwl = tb->e[itable]; else if (tabstyle == LINEAR){ if (itable >= tlm1) error->one(FLERR,"Density > table outer cutoff"); if(itable==0) fraction_i=0.0; else fraction_i = (((rho[i]*rho[i]) - tb->rsq[itable]) * tb->invdelta); evdwl = tb->e[itable] + fraction_i*tb->de[itable]; } else error->one(FLERR,"Only LOOKUP and LINEAR table styles have been implemented for pair multi/lucy"); evdwl *=(pi*cutsq[itype][itype]*cutsq[itype][itype])/84.0; if (evflag) ev_tally(0,0,nlocal,newton_pair, evdwl,0.0,0.0,0.0,0.0,0.0); } if (vflag_fdotr) virial_fdotr_compute(); } /* ---------------------------------------------------------------------- allocate all arrays ------------------------------------------------------------------------- */ void PairMultiLucy::allocate() { allocated = 1; const int nt = atom->ntypes + 1; memory->create(setflag,nt,nt,"pair:setflag"); memory->create(cutsq,nt,nt,"pair:cutsq"); memory->create(tabindex,nt,nt,"pair:tabindex"); memset(&setflag[0][0],0,nt*nt*sizeof(int)); memset(&cutsq[0][0],0,nt*nt*sizeof(double)); memset(&tabindex[0][0],0,nt*nt*sizeof(int)); } /* ---------------------------------------------------------------------- global settings ------------------------------------------------------------------------- */ void PairMultiLucy::settings(int narg, char **arg) { if (narg != 2) error->all(FLERR,"Illegal pair_style command"); // new settings if (strcmp(arg[0],"lookup") == 0) tabstyle = LOOKUP; else if (strcmp(arg[0],"linear") == 0) tabstyle = LINEAR; else error->all(FLERR,"Unknown table style in pair_style command"); tablength = force->inumeric(FLERR,arg[1]); if (tablength < 2) error->all(FLERR,"Illegal number of pair table entries"); // delete old tables, since cannot just change settings for (int m = 0; m < ntables; m++) free_table(&tables[m]); memory->sfree(tables); if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); memory->destroy(tabindex); } allocated = 0; ntables = 0; tables = NULL; } /* ---------------------------------------------------------------------- set coeffs for one or more type pairs ------------------------------------------------------------------------- */ void PairMultiLucy::coeff(int narg, char **arg) { if (narg != 4 && narg != 5) error->all(FLERR,"Illegal pair_coeff command"); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; force->bounds(arg[0],atom->ntypes,ilo,ihi); force->bounds(arg[1],atom->ntypes,jlo,jhi); int me; MPI_Comm_rank(world,&me); tables = (Table *) memory->srealloc(tables,(ntables+1)*sizeof(Table),"pair:tables"); Table *tb = &tables[ntables]; null_table(tb); if (me == 0) read_table(tb,arg[2],arg[3]); bcast_table(tb); // set table cutoff if (narg == 5) tb->cut = force->numeric(FLERR,arg[4]); else if (tb->rflag) tb->cut = tb->rhi; else tb->cut = tb->rfile[tb->ninput-1]; // error check on table parameters // insure cutoff is within table if (tb->ninput <= 1) error->one(FLERR,"Invalid pair table length"); double rlo; if (tb->rflag == 0) { rlo = tb->rfile[0]; } else { rlo = tb->rlo; } rho_0 = rlo; tb->match = 0; if (tabstyle == LINEAR && tb->ninput == tablength && tb->rflag == RSQ) tb->match = 1; // spline read-in values and compute r,e,f vectors within table if (tb->match == 0) spline_table(tb); compute_table(tb); // store ptr to table in tabindex int count = 0; for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { tabindex[i][j] = ntables; setflag[i][j] = 1; count++; } } if (count == 0) error->all(FLERR,"Illegal pair_coeff command"); ntables++; } /* ---------------------------------------------------------------------- init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ double PairMultiLucy::init_one(int i, int j) { if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); tabindex[j][i] = tabindex[i][j]; return tables[tabindex[i][j]].cut; } /* ---------------------------------------------------------------------- read a table section from a tabulated potential file only called by proc 0 this function sets these values in Table: ninput,rfile,efile,ffile,rflag,rlo,rhi,fpflag,fplo,fphi ------------------------------------------------------------------------- */ void PairMultiLucy::read_table(Table *tb, char *file, char *keyword) { char line[MAXLINE]; // open file FILE *fp = fopen(file,"r"); if (fp == NULL) { char str[128]; sprintf(str,"Cannot open file %s",file); error->one(FLERR,str); } // loop until section found with matching keyword while (1) { if (fgets(line,MAXLINE,fp) == NULL) error->one(FLERR,"Did not find keyword in table file"); if (strspn(line," \t\n\r") == strlen(line)) continue; // blank line if (line[0] == '#') continue; // comment char *word = strtok(line," \t\n\r"); if (strcmp(word,keyword) == 0) break; // matching keyword fgets(line,MAXLINE,fp); // no match, skip section param_extract(tb,line); fgets(line,MAXLINE,fp); for (int i = 0; i < tb->ninput; i++) fgets(line,MAXLINE,fp); } // read args on 2nd line of section // allocate table arrays for file values fgets(line,MAXLINE,fp); param_extract(tb,line); memory->create(tb->rfile,tb->ninput,"pair:rfile"); memory->create(tb->efile,tb->ninput,"pair:efile"); memory->create(tb->ffile,tb->ninput,"pair:ffile"); // read r,e,f table values from file // if rflag set, compute r // if rflag not set, use r from file int itmp; double rtmp; fgets(line,MAXLINE,fp); for (int i = 0; i < tb->ninput; i++) { fgets(line,MAXLINE,fp); sscanf(line,"%d %lg %lg %lg",&itmp,&rtmp,&tb->efile[i],&tb->ffile[i]); if (tb->rflag == RLINEAR) rtmp = tb->rlo + (tb->rhi - tb->rlo)*i/(tb->ninput-1); else if (tb->rflag == RSQ) { rtmp = tb->rlo*tb->rlo + (tb->rhi*tb->rhi - tb->rlo*tb->rlo)*i/(tb->ninput-1); rtmp = sqrt(rtmp); } tb->rfile[i] = rtmp; } // close file fclose(fp); } /* ---------------------------------------------------------------------- broadcast read-in table info from proc 0 to other procs this function communicates these values in Table: ninput,rfile,efile,ffile,rflag,rlo,rhi,fpflag,fplo,fphi ------------------------------------------------------------------------- */ void PairMultiLucy::bcast_table(Table *tb) { MPI_Bcast(&tb->ninput,1,MPI_INT,0,world); int me; MPI_Comm_rank(world,&me); if (me > 0) { memory->create(tb->rfile,tb->ninput,"pair:rfile"); memory->create(tb->efile,tb->ninput,"pair:efile"); memory->create(tb->ffile,tb->ninput,"pair:ffile"); } MPI_Bcast(tb->rfile,tb->ninput,MPI_DOUBLE,0,world); MPI_Bcast(tb->efile,tb->ninput,MPI_DOUBLE,0,world); MPI_Bcast(tb->ffile,tb->ninput,MPI_DOUBLE,0,world); MPI_Bcast(&tb->rflag,1,MPI_INT,0,world); if (tb->rflag) { MPI_Bcast(&tb->rlo,1,MPI_DOUBLE,0,world); MPI_Bcast(&tb->rhi,1,MPI_DOUBLE,0,world); } MPI_Bcast(&tb->fpflag,1,MPI_INT,0,world); if (tb->fpflag) { MPI_Bcast(&tb->fplo,1,MPI_DOUBLE,0,world); MPI_Bcast(&tb->fphi,1,MPI_DOUBLE,0,world); } } /* ---------------------------------------------------------------------- build spline representation of e,f over entire range of read-in table this function sets these values in Table: e2file,f2file ------------------------------------------------------------------------- */ void PairMultiLucy::spline_table(Table *tb) { memory->create(tb->e2file,tb->ninput,"pair:e2file"); memory->create(tb->f2file,tb->ninput,"pair:f2file"); double ep0 = - tb->ffile[0]; double epn = - tb->ffile[tb->ninput-1]; spline(tb->rfile,tb->efile,tb->ninput,ep0,epn,tb->e2file); if (tb->fpflag == 0) { tb->fplo = (tb->ffile[1] - tb->ffile[0]) / (tb->rfile[1] - tb->rfile[0]); tb->fphi = (tb->ffile[tb->ninput-1] - tb->ffile[tb->ninput-2]) / (tb->rfile[tb->ninput-1] - tb->rfile[tb->ninput-2]); } double fp0 = tb->fplo; double fpn = tb->fphi; spline(tb->rfile,tb->ffile,tb->ninput,fp0,fpn,tb->f2file); } /* ---------------------------------------------------------------------- extract attributes from parameter line in table section format of line: N value R/RSQ lo hi FP fplo fphi N is required, other params are optional ------------------------------------------------------------------------- */ void PairMultiLucy::param_extract(Table *tb, char *line) { tb->ninput = 0; tb->rflag = NONE; tb->fpflag = 0; char *word = strtok(line," \t\n\r\f"); while (word) { if (strcmp(word,"N") == 0) { word = strtok(NULL," \t\n\r\f"); tb->ninput = atoi(word); } else if (strcmp(word,"R") == 0 || strcmp(word,"RSQ") == 0) { if (strcmp(word,"R") == 0) tb->rflag = RLINEAR; else if (strcmp(word,"RSQ") == 0) tb->rflag = RSQ; word = strtok(NULL," \t\n\r\f"); tb->rlo = atof(word); word = strtok(NULL," \t\n\r\f"); tb->rhi = atof(word); } else if (strcmp(word,"FP") == 0) { tb->fpflag = 1; word = strtok(NULL," \t\n\r\f"); tb->fplo = atof(word); word = strtok(NULL," \t\n\r\f"); tb->fphi = atof(word); } else { printf("WORD: %s\n",word); error->one(FLERR,"Invalid keyword in pair table parameters"); } word = strtok(NULL," \t\n\r\f"); } if (tb->ninput == 0) error->one(FLERR,"Pair table parameters did not set N"); } /* ---------------------------------------------------------------------- compute r,e,f vectors from splined values ------------------------------------------------------------------------- */ void PairMultiLucy::compute_table(Table *tb) { int tlm1 = tablength-1; // inner = inner table bound // cut = outer table bound // delta = table spacing in rsq for N-1 bins double inner; if (tb->rflag) inner = tb->rlo; else inner = tb->rfile[0]; tb->innersq = inner*inner; tb->delta = (tb->rhi*tb->rhi - tb->innersq) / tlm1; tb->invdelta = 1.0/tb->delta; // direct lookup tables // N-1 evenly spaced bins in rsq from inner to cut // e,f = value at midpt of bin // e,f are N-1 in length since store 1 value at bin midpt // f is converted to f/r when stored in f[i] // e,f are never a match to read-in values, always computed via spline interp if (tabstyle == LOOKUP) { memory->create(tb->e,tlm1,"pair:e"); memory->create(tb->f,tlm1,"pair:f"); double r,rsq; for (int i = 0; i < tlm1; i++) { rsq = tb->innersq + (i+0.5)*tb->delta; r = sqrt(rsq); tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r); } } // linear tables // N-1 evenly spaced bins in rsq from inner to cut // rsq,e,f = value at lower edge of bin // de,df values = delta from lower edge to upper edge of bin // rsq,e,f are N in length so de,df arrays can compute difference // f is converted to f/r when stored in f[i] // e,f can match read-in values, else compute via spline interp if (tabstyle == LINEAR) { memory->create(tb->rsq,tablength,"pair:rsq"); memory->create(tb->e,tablength,"pair:e"); memory->create(tb->f,tablength,"pair:f"); memory->create(tb->de,tlm1,"pair:de"); memory->create(tb->df,tlm1,"pair:df"); double r,rsq; for (int i = 0; i < tablength; i++) { rsq = tb->innersq + i*tb->delta; r = sqrt(rsq); tb->rsq[i] = rsq; if (tb->match) { tb->e[i] = tb->efile[i]; tb->f[i] = tb->ffile[i]; } else { tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r); } } for (int i = 0; i < tlm1; i++) { tb->de[i] = tb->e[i+1] - tb->e[i]; tb->df[i] = tb->f[i+1] - tb->f[i]; } } } /* ---------------------------------------------------------------------- set all ptrs in a table to NULL, so can be freed safely ------------------------------------------------------------------------- */ void PairMultiLucy::null_table(Table *tb) { tb->rfile = tb->efile = tb->ffile = NULL; tb->e2file = tb->f2file = NULL; tb->rsq = tb->drsq = tb->e = tb->de = NULL; tb->f = tb->df = tb->e2 = tb->f2 = NULL; } /* ---------------------------------------------------------------------- free all arrays in a table ------------------------------------------------------------------------- */ void PairMultiLucy::free_table(Table *tb) { memory->destroy(tb->rfile); memory->destroy(tb->efile); memory->destroy(tb->ffile); memory->destroy(tb->e2file); memory->destroy(tb->f2file); memory->destroy(tb->rsq); memory->destroy(tb->drsq); memory->destroy(tb->e); memory->destroy(tb->de); memory->destroy(tb->f); memory->destroy(tb->df); memory->destroy(tb->e2); memory->destroy(tb->f2); } /* ---------------------------------------------------------------------- spline and splint routines modified from Numerical Recipes ------------------------------------------------------------------------- */ void PairMultiLucy::spline(double *x, double *y, int n, double yp1, double ypn, double *y2) { int i,k; double p,qn,sig,un; double *u = new double[n]; if (yp1 > 0.99e30) y2[0] = u[0] = 0.0; else { y2[0] = -0.5; u[0] = (3.0/(x[1]-x[0])) * ((y[1]-y[0]) / (x[1]-x[0]) - yp1); } for (i = 1; i < n-1; i++) { sig = (x[i]-x[i-1]) / (x[i+1]-x[i-1]); p = sig*y2[i-1] + 2.0; y2[i] = (sig-1.0) / p; u[i] = (y[i+1]-y[i]) / (x[i+1]-x[i]) - (y[i]-y[i-1]) / (x[i]-x[i-1]); u[i] = (6.0*u[i] / (x[i+1]-x[i-1]) - sig*u[i-1]) / p; } if (ypn > 0.99e30) qn = un = 0.0; else { qn = 0.5; un = (3.0/(x[n-1]-x[n-2])) * (ypn - (y[n-1]-y[n-2]) / (x[n-1]-x[n-2])); } y2[n-1] = (un-qn*u[n-2]) / (qn*y2[n-2] + 1.0); for (k = n-2; k >= 0; k--) y2[k] = y2[k]*y2[k+1] + u[k]; delete [] u; } /* ---------------------------------------------------------------------- */ double PairMultiLucy::splint(double *xa, double *ya, double *y2a, int n, double x) { int klo,khi,k; double h,b,a,y; klo = 0; khi = n-1; while (khi-klo > 1) { k = (khi+klo) >> 1; if (xa[k] > x) khi = k; else klo = k; } h = xa[khi]-xa[klo]; a = (xa[khi]-x) / h; b = (x-xa[klo]) / h; y = a*ya[klo] + b*ya[khi] + ((a*a*a-a)*y2a[klo] + (b*b*b-b)*y2a[khi]) * (h*h)/6.0; return y; } /* ---------------------------------------------------------------------- proc 0 writes to restart file ------------------------------------------------------------------------- */ void PairMultiLucy::write_restart(FILE *fp) { write_restart_settings(fp); } /* ---------------------------------------------------------------------- proc 0 reads from restart file, bcasts ------------------------------------------------------------------------- */ void PairMultiLucy::read_restart(FILE *fp) { read_restart_settings(fp); allocate(); } /* ---------------------------------------------------------------------- proc 0 writes to restart file ------------------------------------------------------------------------- */ void PairMultiLucy::write_restart_settings(FILE *fp) { fwrite(&tabstyle,sizeof(int),1,fp); fwrite(&tablength,sizeof(int),1,fp); } /* ---------------------------------------------------------------------- proc 0 reads from restart file, bcasts ------------------------------------------------------------------------- */ void PairMultiLucy::read_restart_settings(FILE *fp) { if (comm->me == 0) { fread(&tabstyle,sizeof(int),1,fp); fread(&tablength,sizeof(int),1,fp); } MPI_Bcast(&tabstyle,1,MPI_INT,0,world); MPI_Bcast(&tablength,1,MPI_INT,0,world); } /* ---------------------------------------------------------------------- */ void PairMultiLucy::computeLocalDensity() { int i,j,m,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz; double rsq; int *ilist,*jlist,*numneigh,**firstneigh; double **x = atom->x; int *type = atom->type; int nlocal = atom->nlocal; int newton_pair = force->newton_pair; double factor; inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; double pi = MathConst::MY_PI; double *rho = atom->rho; // zero out density if (newton_pair) { m = nlocal + atom->nghost; for (i = 0; i < m; i++) rho[i] = 0.0; } else for (i = 0; i < nlocal; i++) rho[i] = 0.0; // rho = density at each atom // loop over neighbors of my atoms for (ii = 0; ii < inum; ii++) { i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; jlist = firstneigh[i]; jnum = numneigh[i]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; j &= NEIGHMASK; jtype = type[j]; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; rsq = delx*delx + dely*dely + delz*delz; if (rsq < cutsq[itype][jtype]) { double rcut = sqrt(cutsq[itype][jtype]); factor= (84.0/(5.0*pi*rcut*rcut*rcut))*(1.0+3.0*sqrt(rsq)/(2.0*rcut))*(1.0-sqrt(rsq)/rcut)*(1.0-sqrt(rsq)/rcut)*(1.0-sqrt(rsq)/rcut)*(1.0-sqrt(rsq)/rcut); rho[i] += factor; if (newton_pair || j < nlocal) { rho[j] += factor; } } } } if (newton_pair) comm->reverse_comm_pair(this); comm->forward_comm_pair(this); } /* ---------------------------------------------------------------------- */ int PairMultiLucy::pack_forward_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double *rho = atom->rho; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = rho[j]; } return m; } /* ---------------------------------------------------------------------- */ void PairMultiLucy::unpack_forward_comm(int n, int first, double *buf) { int i,m,last; double *rho = atom->rho; m = 0; last = first + n; for (i = first; i < last; i++) rho[i] = buf[m++]; } /* ---------------------------------------------------------------------- */ int PairMultiLucy::pack_reverse_comm(int n, int first, double *buf) { int i,m,last; double *rho = atom->rho; m = 0; last = first + n; for (i = first; i < last; i++) buf[m++] = rho[i]; return m; } /* ---------------------------------------------------------------------- */ void PairMultiLucy::unpack_reverse_comm(int n, int *list, double *buf) { int i,j,m; double *rho = atom->rho; m = 0; for (i = 0; i < n; i++) { j = list[i]; rho[j] += buf[m++]; } } diff --git a/src/USER-DPD/pair_multi_lucy_rx.cpp b/src/USER-DPD/pair_multi_lucy_rx.cpp index 0a1bb4b10..de8673372 100644 --- a/src/USER-DPD/pair_multi_lucy_rx.cpp +++ b/src/USER-DPD/pair_multi_lucy_rx.cpp @@ -1,1023 +1,1023 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------- Contributing authors: James Larentzos and Joshua Moore (U.S. Army Research Laboratory) Please cite the related publications: J.D. Moore, B.C. Barnes, S. Izvekov, M. Lisal, M.S. Sellers, D.E. Taylor & J.K. Brennan "A coarse-grain force field for RDX: Density dependent and energy conserving" The Journal of Chemical Physics, 2016, 144, 104501. ------------------------------------------------------------------------------------------- */ -#include "mpi.h" +#include #include #include "math_const.h" #include #include #include "pair_multi_lucy_rx.h" #include "atom.h" #include "force.h" #include "comm.h" #include "neigh_list.h" #include "memory.h" #include "error.h" #include "citeme.h" #include "modify.h" #include "fix.h" using namespace LAMMPS_NS; enum{NONE,RLINEAR,RSQ}; #define MAXLINE 1024 #define oneFluidParameter (-1) #define isOneFluid(_site) ( (_site) == oneFluidParameter ) static const char cite_pair_multi_lucy_rx[] = "pair_style multi/lucy/rx command:\n\n" "@Article{Moore16,\n" " author = {J.D. Moore, B.C. Barnes, S. Izvekov, M. Lisal, M.S. Sellers, D.E. Taylor and J. K. Brennan},\n" " title = {A coarse-grain force field for RDX: Density dependent and energy conserving},\n" " journal = {J. Chem. Phys.},\n" " year = 2016,\n" " volume = 144\n" " pages = {104501}\n" "}\n\n"; /* ---------------------------------------------------------------------- */ PairMultiLucyRX::PairMultiLucyRX(LAMMPS *lmp) : Pair(lmp) { if (lmp->citeme) lmp->citeme->add(cite_pair_multi_lucy_rx); if (atom->rho_flag != 1) error->all(FLERR,"Pair multi/lucy/rx command requires atom_style with density (e.g. dpd, meso)"); ntables = 0; tables = NULL; comm_forward = 1; comm_reverse = 1; } /* ---------------------------------------------------------------------- */ PairMultiLucyRX::~PairMultiLucyRX() { for (int m = 0; m < ntables; m++) free_table(&tables[m]); memory->sfree(tables); if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); memory->destroy(tabindex); } } /* ---------------------------------------------------------------------- */ void PairMultiLucyRX::compute(int eflag, int vflag) { int i,j,ii,jj,inum,jnum,itype,jtype,itable; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,evdwlOld,fpair; double rsq; int *ilist,*jlist,*numneigh,**firstneigh; Table *tb; int tlm1 = tablength - 1; evdwlOld = 0.0; evdwl = 0.0; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; double **x = atom->x; double **f = atom->f; int *type = atom->type; int nlocal = atom->nlocal; int nghost = atom->nghost; int newton_pair = force->newton_pair; double fractionOld1_i,fractionOld1_j; double fractionOld2_i,fractionOld2_j; double fraction1_i; double *uCG = atom->uCG; double *uCGnew = atom->uCGnew; double pi = MathConst::MY_PI; double A_i, A_j; double fraction_i,fraction_j; int jtable; double *rho = atom->rho; double *fractionOld1 = NULL; double *fractionOld2 = NULL; double *fraction1 = NULL; double *fraction2 = NULL; { const int ntotal = nlocal + nghost; memory->create(fractionOld1, ntotal, "PairMultiLucyRX::fractionOld1"); memory->create(fractionOld2, ntotal, "PairMultiLucyRX::fractionOld2"); memory->create(fraction1, ntotal, "PairMultiLucyRX::fraction1"); memory->create(fraction2, ntotal, "PairMultiLucyRX::fraction2"); for (int i = 0; i < ntotal; ++i) getParams(i, fractionOld1[i], fractionOld2[i], fraction1[i], fraction2[i]); } inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; computeLocalDensity(); // loop over neighbors of my atoms for (ii = 0; ii < inum; ii++) { i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; jlist = firstneigh[i]; jnum = numneigh[i]; double fx_i = 0.0; double fy_i = 0.0; double fz_i = 0.0; fractionOld1_i = fractionOld1[i]; fractionOld2_i = fractionOld2[i]; fraction1_i = fraction1[i]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; j &= NEIGHMASK; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; rsq = delx*delx + dely*dely + delz*delz; jtype = type[j]; if (rsq < cutsq[itype][jtype]) { fpair = 0.0; fractionOld1_j = fractionOld1[j]; fractionOld2_j = fractionOld2[j]; tb = &tables[tabindex[itype][jtype]]; if (rho[i]*rho[i] < tb->innersq || rho[j]*rho[j] < tb->innersq){ printf("Table inner cutoff = %lf\n",sqrt(tb->innersq)); printf("rho[%d]=%lf\n",i,rho[i]); printf("rho[%d]=%lf\n",j,rho[j]); error->one(FLERR,"Density < table inner cutoff"); } if (tabstyle == LOOKUP) { itable = static_cast (((rho[i]*rho[i]) - tb->innersq) * tb->invdelta); jtable = static_cast (((rho[j]*rho[j]) - tb->innersq) * tb->invdelta); if (itable >= tlm1 || jtable >= tlm1){ printf("Table outer index = %d\n",tlm1); printf("itableIndex=%d rho[%d]=%lf\n",itable,i,rho[i]); printf("jtableIndex=%d rho[%d]=%lf\n",jtable,j,rho[j]); error->one(FLERR,"Density > table outer cutoff"); } A_i = tb->f[itable]; A_j = tb->f[jtable]; const double rfactor = 1.0-sqrt(rsq/cutsq[itype][jtype]); fpair = 0.5*(A_i + A_j)*(4.0-3.0*rfactor)*rfactor*rfactor*rfactor; fpair /= sqrt(rsq); } else if (tabstyle == LINEAR) { itable = static_cast ((rho[i]*rho[i] - tb->innersq) * tb->invdelta); jtable = static_cast (((rho[j]*rho[j]) - tb->innersq) * tb->invdelta); if (itable >= tlm1 || jtable >= tlm1){ printf("Table outer index = %d\n",tlm1); printf("itableIndex=%d rho[%d]=%lf\n",itable,i,rho[i]); printf("jtableIndex=%d rho[%d]=%lf\n",jtable,j,rho[j]); error->one(FLERR,"Density > table outer cutoff"); } if(itable<0) itable=0; if(itable>=tlm1) itable=tlm1; if(jtable<0) jtable=0; if(jtable>=tlm1)jtable=tlm1; fraction_i = (((rho[i]*rho[i]) - tb->rsq[itable]) * tb->invdelta); fraction_j = (((rho[j]*rho[j]) - tb->rsq[jtable]) * tb->invdelta); if(itable==0) fraction_i=0.0; if(itable==tlm1) fraction_i=0.0; if(jtable==0) fraction_j=0.0; if(jtable==tlm1) fraction_j=0.0; A_i = tb->f[itable] + fraction_i*tb->df[itable]; A_j = tb->f[jtable] + fraction_j*tb->df[jtable]; const double rfactor = 1.0-sqrt(rsq/cutsq[itype][jtype]); fpair = 0.5*(A_i + A_j)*(4.0-3.0*rfactor)*rfactor*rfactor*rfactor; fpair /= sqrt(rsq); } else error->one(FLERR,"Only LOOKUP and LINEAR table styles have been implemented for pair multi/lucy/rx"); if (isite1 == isite2) fpair = sqrt(fractionOld1_i*fractionOld2_j)*fpair; else fpair = (sqrt(fractionOld1_i*fractionOld2_j) + sqrt(fractionOld2_i*fractionOld1_j))*fpair; fx_i += delx*fpair; fy_i += dely*fpair; fz_i += delz*fpair; if (newton_pair || j < nlocal) { f[j][0] -= delx*fpair; f[j][1] -= dely*fpair; f[j][2] -= delz*fpair; } if (evflag) ev_tally(i,j,nlocal,newton_pair,0.0,0.0,fpair,delx,dely,delz); } } f[i][0] += fx_i; f[i][1] += fy_i; f[i][2] += fz_i; tb = &tables[tabindex[itype][itype]]; itable = static_cast (((rho[i]*rho[i]) - tb->innersq) * tb->invdelta); if (tabstyle == LOOKUP) evdwl = tb->e[itable]; else if (tabstyle == LINEAR){ if (itable >= tlm1){ printf("itableIndex=%d rho[%d]=%lf\n",itable,i,rho[i]); error->one(FLERR,"Density > table outer cutoff"); } if(itable==0) fraction_i=0.0; else fraction_i = (((rho[i]*rho[i]) - tb->rsq[itable]) * tb->invdelta); evdwl = tb->e[itable] + fraction_i*tb->de[itable]; } else error->one(FLERR,"Only LOOKUP and LINEAR table styles have been implemented for pair multi/lucy/rx"); evdwl *=(pi*cutsq[itype][itype]*cutsq[itype][itype])/84.0; evdwlOld = fractionOld1_i*evdwl; evdwl = fraction1_i*evdwl; uCG[i] += evdwlOld; uCGnew[i] += evdwl; evdwl = evdwlOld; if (evflag) ev_tally(0,0,nlocal,newton_pair,evdwl,0.0,0.0,0.0,0.0,0.0); } if (vflag_fdotr) virial_fdotr_compute(); memory->destroy(fractionOld1); memory->destroy(fractionOld2); memory->destroy(fraction1); memory->destroy(fraction2); } /* ---------------------------------------------------------------------- allocate all arrays ------------------------------------------------------------------------- */ void PairMultiLucyRX::allocate() { allocated = 1; const int nt = atom->ntypes + 1; memory->create(setflag,nt,nt,"pair:setflag"); memory->create(cutsq,nt,nt,"pair:cutsq"); memory->create(tabindex,nt,nt,"pair:tabindex"); memset(&setflag[0][0],0,nt*nt*sizeof(int)); memset(&cutsq[0][0],0,nt*nt*sizeof(double)); memset(&tabindex[0][0],0,nt*nt*sizeof(int)); } /* ---------------------------------------------------------------------- global settings ------------------------------------------------------------------------- */ void PairMultiLucyRX::settings(int narg, char **arg) { if (narg != 2) error->all(FLERR,"Illegal pair_style command"); // new settings if (strcmp(arg[0],"lookup") == 0) tabstyle = LOOKUP; else if (strcmp(arg[0],"linear") == 0) tabstyle = LINEAR; else error->all(FLERR,"Unknown table style in pair_style command"); tablength = force->inumeric(FLERR,arg[1]); if (tablength < 2) error->all(FLERR,"Illegal number of pair table entries"); // delete old tables, since cannot just change settings for (int m = 0; m < ntables; m++) free_table(&tables[m]); memory->sfree(tables); if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); memory->destroy(tabindex); } allocated = 0; ntables = 0; tables = NULL; } /* ---------------------------------------------------------------------- set coeffs for one or more type pairs ------------------------------------------------------------------------- */ void PairMultiLucyRX::coeff(int narg, char **arg) { if (narg != 6 && narg != 7) error->all(FLERR,"Illegal pair_coeff command"); bool rx_flag = false; for (int i = 0; i < modify->nfix; i++) if (strncmp(modify->fix[i]->style,"rx",2) == 0) rx_flag = true; if (!rx_flag) error->all(FLERR,"PairMultiLucyRX requires a fix rx command."); if (!allocated) allocate(); int ilo,ihi,jlo,jhi; force->bounds(arg[0],atom->ntypes,ilo,ihi); force->bounds(arg[1],atom->ntypes,jlo,jhi); int me; MPI_Comm_rank(world,&me); tables = (Table *) memory->srealloc(tables,(ntables+1)*sizeof(Table),"pair:tables"); Table *tb = &tables[ntables]; null_table(tb); if (me == 0) read_table(tb,arg[2],arg[3]); bcast_table(tb); nspecies = atom->nspecies_dpd; int n; n = strlen(arg[3]) + 1; site1 = new char[n]; strcpy(site1,arg[4]); n = strlen(arg[4]) + 1; site2 = new char[n]; strcpy(site2,arg[5]); // set table cutoff if (narg == 7) tb->cut = force->numeric(FLERR,arg[6]); else if (tb->rflag) tb->cut = tb->rhi; else tb->cut = tb->rfile[tb->ninput-1]; // error check on table parameters // insure cutoff is within table if (tb->ninput <= 1) error->one(FLERR,"Invalid pair table length"); if (tb->rflag == 0) { rho_0 = tb->rfile[0]; } else { rho_0 = tb->rlo; } tb->match = 0; if (tabstyle == LINEAR && tb->ninput == tablength && tb->rflag == RSQ) tb->match = 1; // spline read-in values and compute r,e,f vectors within table if (tb->match == 0) spline_table(tb); compute_table(tb); // store ptr to table in tabindex int count = 0; for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { tabindex[i][j] = ntables; setflag[i][j] = 1; count++; } } if (count == 0) error->all(FLERR,"Illegal pair_coeff command"); ntables++; // Match site* to isite values. if (strcmp(site1, "1fluid") == 0) isite1 = oneFluidParameter; else { isite1 = nspecies; for (int ispecies = 0; ispecies < nspecies; ++ispecies) if (strcmp(site1, atom->dname[ispecies]) == 0){ isite1 = ispecies; break; } if (isite1 == nspecies) error->all(FLERR,"Pair_multi_lucy_rx site1 is invalid."); } if (strcmp(site2, "1fluid") == 0) isite2 = oneFluidParameter; else { isite2 = nspecies; for (int ispecies = 0; ispecies < nspecies; ++ispecies) if (strcmp(site2, atom->dname[ispecies]) == 0){ isite2 = ispecies; break; } if (isite2 == nspecies) error->all(FLERR,"Pair_multi_lucy_rx site2 is invalid."); } } /* ---------------------------------------------------------------------- init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ double PairMultiLucyRX::init_one(int i, int j) { if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); tabindex[j][i] = tabindex[i][j]; return tables[tabindex[i][j]].cut; } /* ---------------------------------------------------------------------- read a table section from a tabulated potential file only called by proc 0 this function sets these values in Table: ninput,rfile,efile,ffile,rflag,rlo,rhi,fpflag,fplo,fphi ------------------------------------------------------------------------- */ void PairMultiLucyRX::read_table(Table *tb, char *file, char *keyword) { char line[MAXLINE]; // open file FILE *fp = force->open_potential(file); if (fp == NULL) { char str[128]; sprintf(str,"Cannot open file %s",file); error->one(FLERR,str); } // loop until section found with matching keyword while (1) { if (fgets(line,MAXLINE,fp) == NULL) error->one(FLERR,"Did not find keyword in table file"); if (strspn(line," \t\n\r") == strlen(line)) continue; // blank line if (line[0] == '#') continue; // comment char *word = strtok(line," \t\n\r"); if (strcmp(word,keyword) == 0) break; // matching keyword fgets(line,MAXLINE,fp); // no match, skip section param_extract(tb,line); fgets(line,MAXLINE,fp); for (int i = 0; i < tb->ninput; i++) fgets(line,MAXLINE,fp); } // read args on 2nd line of section // allocate table arrays for file values fgets(line,MAXLINE,fp); param_extract(tb,line); memory->create(tb->rfile,tb->ninput,"pair:rfile"); memory->create(tb->efile,tb->ninput,"pair:efile"); memory->create(tb->ffile,tb->ninput,"pair:ffile"); // read r,e,f table values from file // if rflag set, compute r // if rflag not set, use r from file int itmp; double rtmp; fgets(line,MAXLINE,fp); for (int i = 0; i < tb->ninput; i++) { fgets(line,MAXLINE,fp); sscanf(line,"%d %lg %lg %lg",&itmp,&rtmp,&tb->efile[i],&tb->ffile[i]); if (tb->rflag == RLINEAR) rtmp = tb->rlo + (tb->rhi - tb->rlo)*i/(tb->ninput-1); else if (tb->rflag == RSQ) { rtmp = tb->rlo*tb->rlo + (tb->rhi*tb->rhi - tb->rlo*tb->rlo)*i/(tb->ninput-1); rtmp = sqrt(rtmp); } tb->rfile[i] = rtmp; } // close file fclose(fp); } /* ---------------------------------------------------------------------- broadcast read-in table info from proc 0 to other procs this function communicates these values in Table: ninput,rfile,efile,ffile,rflag,rlo,rhi,fpflag,fplo,fphi ------------------------------------------------------------------------- */ void PairMultiLucyRX::bcast_table(Table *tb) { MPI_Bcast(&tb->ninput,1,MPI_INT,0,world); int me; MPI_Comm_rank(world,&me); if (me > 0) { memory->create(tb->rfile,tb->ninput,"pair:rfile"); memory->create(tb->efile,tb->ninput,"pair:efile"); memory->create(tb->ffile,tb->ninput,"pair:ffile"); } MPI_Bcast(tb->rfile,tb->ninput,MPI_DOUBLE,0,world); MPI_Bcast(tb->efile,tb->ninput,MPI_DOUBLE,0,world); MPI_Bcast(tb->ffile,tb->ninput,MPI_DOUBLE,0,world); MPI_Bcast(&tb->rflag,1,MPI_INT,0,world); if (tb->rflag) { MPI_Bcast(&tb->rlo,1,MPI_DOUBLE,0,world); MPI_Bcast(&tb->rhi,1,MPI_DOUBLE,0,world); } MPI_Bcast(&tb->fpflag,1,MPI_INT,0,world); if (tb->fpflag) { MPI_Bcast(&tb->fplo,1,MPI_DOUBLE,0,world); MPI_Bcast(&tb->fphi,1,MPI_DOUBLE,0,world); } } /* ---------------------------------------------------------------------- build spline representation of e,f over entire range of read-in table this function sets these values in Table: e2file,f2file ------------------------------------------------------------------------- */ void PairMultiLucyRX::spline_table(Table *tb) { memory->create(tb->e2file,tb->ninput,"pair:e2file"); memory->create(tb->f2file,tb->ninput,"pair:f2file"); double ep0 = - tb->ffile[0]; double epn = - tb->ffile[tb->ninput-1]; spline(tb->rfile,tb->efile,tb->ninput,ep0,epn,tb->e2file); if (tb->fpflag == 0) { tb->fplo = (tb->ffile[1] - tb->ffile[0]) / (tb->rfile[1] - tb->rfile[0]); tb->fphi = (tb->ffile[tb->ninput-1] - tb->ffile[tb->ninput-2]) / (tb->rfile[tb->ninput-1] - tb->rfile[tb->ninput-2]); } double fp0 = tb->fplo; double fpn = tb->fphi; spline(tb->rfile,tb->ffile,tb->ninput,fp0,fpn,tb->f2file); } /* ---------------------------------------------------------------------- extract attributes from parameter line in table section format of line: N value R/RSQ lo hi FP fplo fphi N is required, other params are optional ------------------------------------------------------------------------- */ void PairMultiLucyRX::param_extract(Table *tb, char *line) { tb->ninput = 0; tb->rflag = NONE; tb->fpflag = 0; char *word = strtok(line," \t\n\r\f"); while (word) { if (strcmp(word,"N") == 0) { word = strtok(NULL," \t\n\r\f"); tb->ninput = atoi(word); } else if (strcmp(word,"R") == 0 || strcmp(word,"RSQ") == 0) { if (strcmp(word,"R") == 0) tb->rflag = RLINEAR; else if (strcmp(word,"RSQ") == 0) tb->rflag = RSQ; word = strtok(NULL," \t\n\r\f"); tb->rlo = atof(word); word = strtok(NULL," \t\n\r\f"); tb->rhi = atof(word); } else if (strcmp(word,"FP") == 0) { tb->fpflag = 1; word = strtok(NULL," \t\n\r\f"); tb->fplo = atof(word); word = strtok(NULL," \t\n\r\f"); tb->fphi = atof(word); } else { printf("WORD: %s\n",word); error->one(FLERR,"Invalid keyword in pair table parameters"); } word = strtok(NULL," \t\n\r\f"); } if (tb->ninput == 0) error->one(FLERR,"Pair table parameters did not set N"); } /* ---------------------------------------------------------------------- compute r,e,f vectors from splined values ------------------------------------------------------------------------- */ void PairMultiLucyRX::compute_table(Table *tb) { int tlm1 = tablength-1; // inner = inner table bound // cut = outer table bound // delta = table spacing in rsq for N-1 bins double inner; if (tb->rflag) inner = tb->rlo; else inner = tb->rfile[0]; tb->innersq = inner*inner; tb->delta = (tb->rhi*tb->rhi - tb->innersq) / tlm1; tb->invdelta = 1.0/tb->delta; // direct lookup tables // N-1 evenly spaced bins in rsq from inner to cut // e,f = value at midpt of bin // e,f are N-1 in length since store 1 value at bin midpt // f is converted to f/r when stored in f[i] // e,f are never a match to read-in values, always computed via spline interp if (tabstyle == LOOKUP) { memory->create(tb->e,tlm1,"pair:e"); memory->create(tb->f,tlm1,"pair:f"); double r,rsq; for (int i = 0; i < tlm1; i++) { rsq = tb->innersq + (i+0.5)*tb->delta; r = sqrt(rsq); tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r); } } // linear tables // N-1 evenly spaced bins in rsq from inner to cut // rsq,e,f = value at lower edge of bin // de,df values = delta from lower edge to upper edge of bin // rsq,e,f are N in length so de,df arrays can compute difference // f is converted to f/r when stored in f[i] // e,f can match read-in values, else compute via spline interp if (tabstyle == LINEAR) { memory->create(tb->rsq,tablength,"pair:rsq"); memory->create(tb->e,tablength,"pair:e"); memory->create(tb->f,tablength,"pair:f"); memory->create(tb->de,tlm1,"pair:de"); memory->create(tb->df,tlm1,"pair:df"); double r,rsq; for (int i = 0; i < tablength; i++) { rsq = tb->innersq + i*tb->delta; r = sqrt(rsq); tb->rsq[i] = rsq; if (tb->match) { tb->e[i] = tb->efile[i]; tb->f[i] = tb->ffile[i]; } else { tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r); } } for (int i = 0; i < tlm1; i++) { tb->de[i] = tb->e[i+1] - tb->e[i]; tb->df[i] = tb->f[i+1] - tb->f[i]; } } } /* ---------------------------------------------------------------------- set all ptrs in a table to NULL, so can be freed safely ------------------------------------------------------------------------- */ void PairMultiLucyRX::null_table(Table *tb) { tb->rfile = tb->efile = tb->ffile = NULL; tb->e2file = tb->f2file = NULL; tb->rsq = tb->drsq = tb->e = tb->de = NULL; tb->f = tb->df = tb->e2 = tb->f2 = NULL; } /* ---------------------------------------------------------------------- free all arrays in a table ------------------------------------------------------------------------- */ void PairMultiLucyRX::free_table(Table *tb) { memory->destroy(tb->rfile); memory->destroy(tb->efile); memory->destroy(tb->ffile); memory->destroy(tb->e2file); memory->destroy(tb->f2file); memory->destroy(tb->rsq); memory->destroy(tb->drsq); memory->destroy(tb->e); memory->destroy(tb->de); memory->destroy(tb->f); memory->destroy(tb->df); memory->destroy(tb->e2); memory->destroy(tb->f2); } /* ---------------------------------------------------------------------- spline and splint routines modified from Numerical Recipes ------------------------------------------------------------------------- */ void PairMultiLucyRX::spline(double *x, double *y, int n, double yp1, double ypn, double *y2) { int i,k; double p,qn,sig,un; double *u = new double[n]; if (yp1 > 0.99e30) y2[0] = u[0] = 0.0; else { y2[0] = -0.5; u[0] = (3.0/(x[1]-x[0])) * ((y[1]-y[0]) / (x[1]-x[0]) - yp1); } for (i = 1; i < n-1; i++) { sig = (x[i]-x[i-1]) / (x[i+1]-x[i-1]); p = sig*y2[i-1] + 2.0; y2[i] = (sig-1.0) / p; u[i] = (y[i+1]-y[i]) / (x[i+1]-x[i]) - (y[i]-y[i-1]) / (x[i]-x[i-1]); u[i] = (6.0*u[i] / (x[i+1]-x[i-1]) - sig*u[i-1]) / p; } if (ypn > 0.99e30) qn = un = 0.0; else { qn = 0.5; un = (3.0/(x[n-1]-x[n-2])) * (ypn - (y[n-1]-y[n-2]) / (x[n-1]-x[n-2])); } y2[n-1] = (un-qn*u[n-2]) / (qn*y2[n-2] + 1.0); for (k = n-2; k >= 0; k--) y2[k] = y2[k]*y2[k+1] + u[k]; delete [] u; } /* ---------------------------------------------------------------------- */ double PairMultiLucyRX::splint(double *xa, double *ya, double *y2a, int n, double x) { int klo,khi,k; double h,b,a,y; klo = 0; khi = n-1; while (khi-klo > 1) { k = (khi+klo) >> 1; if (xa[k] > x) khi = k; else klo = k; } h = xa[khi]-xa[klo]; a = (xa[khi]-x) / h; b = (x-xa[klo]) / h; y = a*ya[klo] + b*ya[khi] + ((a*a*a-a)*y2a[klo] + (b*b*b-b)*y2a[khi]) * (h*h)/6.0; return y; } /* ---------------------------------------------------------------------- proc 0 writes to restart file ------------------------------------------------------------------------- */ void PairMultiLucyRX::write_restart(FILE *fp) { write_restart_settings(fp); } /* ---------------------------------------------------------------------- proc 0 reads from restart file, bcasts ------------------------------------------------------------------------- */ void PairMultiLucyRX::read_restart(FILE *fp) { read_restart_settings(fp); allocate(); } /* ---------------------------------------------------------------------- proc 0 writes to restart file ------------------------------------------------------------------------- */ void PairMultiLucyRX::write_restart_settings(FILE *fp) { fwrite(&tabstyle,sizeof(int),1,fp); fwrite(&tablength,sizeof(int),1,fp); } /* ---------------------------------------------------------------------- proc 0 reads from restart file, bcasts ------------------------------------------------------------------------- */ void PairMultiLucyRX::read_restart_settings(FILE *fp) { if (comm->me == 0) { fread(&tabstyle,sizeof(int),1,fp); fread(&tablength,sizeof(int),1,fp); } MPI_Bcast(&tabstyle,1,MPI_INT,0,world); MPI_Bcast(&tablength,1,MPI_INT,0,world); } /* ---------------------------------------------------------------------- */ void PairMultiLucyRX::computeLocalDensity() { double **x = atom->x; const int *type = atom->type; const int nlocal = atom->nlocal; const int inum = list->inum; const int *ilist = list->ilist; const int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; const double pi = MathConst::MY_PI; const bool newton_pair = force->newton_pair; const bool one_type = (atom->ntypes == 1); // Special cut-off values for when there's only one type. const double cutsq_type11 = cutsq[1][1]; const double rcut_type11 = sqrt(cutsq_type11); const double factor_type11 = 84.0/(5.0*pi*rcut_type11*rcut_type11*rcut_type11); double *rho = atom->rho; // zero out density if (newton_pair) { const int m = nlocal + atom->nghost; for (int i = 0; i < m; i++) rho[i] = 0.0; } else for (int i = 0; i < nlocal; i++) rho[i] = 0.0; // rho = density at each atom // loop over neighbors of my atoms for (int ii = 0; ii < inum; ii++){ const int i = ilist[ii]; const double xtmp = x[i][0]; const double ytmp = x[i][1]; const double ztmp = x[i][2]; double rho_i = rho[i]; const int itype = type[i]; const int *jlist = firstneigh[i]; const int jnum = numneigh[i]; for (int jj = 0; jj < jnum; jj++){ const int j = (jlist[jj] & NEIGHMASK); const int jtype = type[j]; const double delx = xtmp - x[j][0]; const double dely = ytmp - x[j][1]; const double delz = ztmp - x[j][2]; const double rsq = delx*delx + dely*dely + delz*delz; if (one_type) { if (rsq < cutsq_type11) { const double rcut = rcut_type11; const double r_over_rcut = sqrt(rsq) / rcut; const double tmpFactor = 1.0 - r_over_rcut; const double tmpFactor4 = tmpFactor*tmpFactor*tmpFactor*tmpFactor; const double factor = factor_type11*(1.0 + 1.5*r_over_rcut)*tmpFactor4; rho_i += factor; if (newton_pair || j < nlocal) rho[j] += factor; } else if (rsq < cutsq[itype][jtype]) { const double rcut = sqrt(cutsq[itype][jtype]); const double tmpFactor = 1.0-sqrt(rsq)/rcut; const double tmpFactor4 = tmpFactor*tmpFactor*tmpFactor*tmpFactor; const double factor = (84.0/(5.0*pi*rcut*rcut*rcut))*(1.0+3.0*sqrt(rsq)/(2.0*rcut))*tmpFactor4; rho_i += factor; if (newton_pair || j < nlocal) rho[j] += factor; } } } rho[i] = rho_i; } if (newton_pair) comm->reverse_comm_pair(this); comm->forward_comm_pair(this); } /* ---------------------------------------------------------------------- */ void PairMultiLucyRX::getParams(int id, double &fractionOld1, double &fractionOld2, double &fraction1, double &fraction2) { double fractionOld, fraction; double nTotal, nTotalOld; nTotal = 0.0; nTotalOld = 0.0; for (int ispecies = 0; ispecies < nspecies; ispecies++){ nTotal += atom->dvector[ispecies][id]; nTotalOld += atom->dvector[ispecies+nspecies][id]; } if (isOneFluid(isite1) == false){ fractionOld1 = atom->dvector[isite1+nspecies][id]/nTotalOld; fraction1 = atom->dvector[isite1][id]/nTotal; } if (isOneFluid(isite2) == false){ fractionOld2 = atom->dvector[isite2+nspecies][id]/nTotalOld; fraction2 = atom->dvector[isite2][id]/nTotal; } if (isOneFluid(isite1) || isOneFluid(isite2)){ fractionOld = 0.0; fraction = 0.0; for (int ispecies = 0; ispecies < nspecies; ispecies++){ if (isite1 == ispecies || isite2 == ispecies) continue; fractionOld += atom->dvector[ispecies+nspecies][id] / nTotalOld; fraction += atom->dvector[ispecies][id] / nTotal; } if (isOneFluid(isite1)){ fractionOld1 = fractionOld; fraction1 = fraction; } if (isOneFluid(isite2)){ fractionOld2 = fractionOld; fraction2 = fraction; } } } /* ---------------------------------------------------------------------- */ int PairMultiLucyRX::pack_forward_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double *rho = atom->rho; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = rho[j]; } return m; } /* ---------------------------------------------------------------------- */ void PairMultiLucyRX::unpack_forward_comm(int n, int first, double *buf) { int i,m,last; double *rho = atom->rho; m = 0; last = first + n; for (i = first; i < last; i++) rho[i] = buf[m++]; } /* ---------------------------------------------------------------------- */ int PairMultiLucyRX::pack_reverse_comm(int n, int first, double *buf) { int i,m,last; double *rho = atom->rho; m = 0; last = first + n; for (i = first; i < last; i++) buf[m++] = rho[i]; return m; } /* ---------------------------------------------------------------------- */ void PairMultiLucyRX::unpack_reverse_comm(int n, int *list, double *buf) { int i,j,m; double *rho = atom->rho; m = 0; for (i = 0; i < n; i++) { j = list[i]; rho[j] += buf[m++]; } } diff --git a/src/USER-DPD/pair_table_rx.cpp b/src/USER-DPD/pair_table_rx.cpp index d278feaf8..44a9d7602 100644 --- a/src/USER-DPD/pair_table_rx.cpp +++ b/src/USER-DPD/pair_table_rx.cpp @@ -1,1186 +1,1186 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Paul Crozier (SNL) ------------------------------------------------------------------------- */ -#include "mpi.h" +#include #include #include #include #include "pair_table_rx.h" #include "atom.h" #include "force.h" #include "comm.h" #include "neigh_list.h" #include "memory.h" #include "error.h" #include "modify.h" #include "fix.h" using namespace LAMMPS_NS; enum{NONE,RLINEAR,RSQ,BMP}; #define MAXLINE 1024 #define OneFluidValue (-1) #define isOneFluid(_site_) ( (_site_) == OneFluidValue ) /* ---------------------------------------------------------------------- */ PairTableRX::PairTableRX(LAMMPS *lmp) : Pair(lmp) { ntables = 0; tables = NULL; } /* ---------------------------------------------------------------------- */ PairTableRX::~PairTableRX() { for (int m = 0; m < ntables; m++) free_table(&tables[m]); memory->sfree(tables); if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); memory->destroy(tabindex); } } /* ---------------------------------------------------------------------- */ void PairTableRX::compute(int eflag, int vflag) { int i,j,ii,jj,inum,jnum,itype,jtype,itable; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,evdwlOld,fpair; double rsq,factor_lj,fraction,value,a,b; int *ilist,*jlist,*numneigh,**firstneigh; Table *tb; union_int_float_t rsq_lookup; int tlm1 = tablength - 1; fraction = 0.0; a = 0.0; b = 0.0; evdwlOld = 0.0; evdwl = 0.0; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; double *fractionOld1, *fractionOld2; double *fraction1, *fraction2; { const int ntotal = atom->nlocal + atom->nghost; memory->create(fractionOld1, ntotal, "PairTableRx::compute::fractionOld1"); memory->create(fractionOld2, ntotal, "PairTableRx::compute::fractionOld2"); memory->create(fraction1, ntotal, "PairTableRx::compute::fraction1"); memory->create(fraction2, ntotal, "PairTableRx::compute::fraction2"); for (int i = 0; i < ntotal; ++i) getParams(i, fractionOld1[i], fractionOld2[i], fraction1[i], fraction2[i]); } double **x = atom->x; double **f = atom->f; int *type = atom->type; int nlocal = atom->nlocal; double *special_lj = force->special_lj; int newton_pair = force->newton_pair; double fractionOld1_i, fractionOld1_j; double fractionOld2_i, fractionOld2_j; double fraction1_i, fraction1_j; double fraction2_i, fraction2_j; double *uCG = atom->uCG; double *uCGnew = atom->uCGnew; inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; // loop over neighbors of my atoms for (ii = 0; ii < inum; ii++) { i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; jlist = firstneigh[i]; jnum = numneigh[i]; double uCG_i = 0.0; double uCGnew_i = 0.0; double fx_i = 0.0, fy_i = 0.0, fz_i = 0.0; fractionOld1_i = fractionOld1[i]; fractionOld2_i = fractionOld2[i]; fraction1_i = fraction1[i]; fraction2_i = fraction2[i]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; factor_lj = special_lj[sbmask(j)]; j &= NEIGHMASK; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; rsq = delx*delx + dely*dely + delz*delz; jtype = type[j]; if (rsq < cutsq[itype][jtype]) { fractionOld1_j = fractionOld1[j]; fractionOld2_j = fractionOld2[j]; fraction1_j = fraction1[j]; fraction2_j = fraction2[j]; tb = &tables[tabindex[itype][jtype]]; if (rsq < tb->innersq) error->one(FLERR,"Pair distance < table inner cutoff"); if (tabstyle == LOOKUP) { itable = static_cast ((rsq - tb->innersq) * tb->invdelta); if (itable >= tlm1) error->one(FLERR,"Pair distance > table outer cutoff"); fpair = factor_lj * tb->f[itable]; } else if (tabstyle == LINEAR) { itable = static_cast ((rsq - tb->innersq) * tb->invdelta); if (itable >= tlm1) error->one(FLERR,"Pair distance > table outer cutoff"); fraction = (rsq - tb->rsq[itable]) * tb->invdelta; value = tb->f[itable] + fraction*tb->df[itable]; fpair = factor_lj * value; } else if (tabstyle == SPLINE) { itable = static_cast ((rsq - tb->innersq) * tb->invdelta); if (itable >= tlm1) error->one(FLERR,"Pair distance > table outer cutoff"); b = (rsq - tb->rsq[itable]) * tb->invdelta; a = 1.0 - b; value = a * tb->f[itable] + b * tb->f[itable+1] + ((a*a*a-a)*tb->f2[itable] + (b*b*b-b)*tb->f2[itable+1]) * tb->deltasq6; fpair = factor_lj * value; } else { rsq_lookup.f = rsq; itable = rsq_lookup.i & tb->nmask; itable >>= tb->nshiftbits; fraction = (rsq_lookup.f - tb->rsq[itable]) * tb->drsq[itable]; value = tb->f[itable] + fraction*tb->df[itable]; fpair = factor_lj * value; } if (isite1 == isite2) fpair = sqrt(fractionOld1_i*fractionOld2_j)*fpair; else fpair = (sqrt(fractionOld1_i*fractionOld2_j) + sqrt(fractionOld2_i*fractionOld1_j))*fpair; fx_i += delx*fpair; fy_i += dely*fpair; fz_i += delz*fpair; if (newton_pair || j < nlocal) { f[j][0] -= delx*fpair; f[j][1] -= dely*fpair; f[j][2] -= delz*fpair; } if (tabstyle == LOOKUP) evdwl = tb->e[itable]; else if (tabstyle == LINEAR || tabstyle == BITMAP){ evdwl = tb->e[itable] + fraction*tb->de[itable]; } else evdwl = a * tb->e[itable] + b * tb->e[itable+1] + ((a*a*a-a)*tb->e2[itable] + (b*b*b-b)*tb->e2[itable+1]) * tb->deltasq6; if (isite1 == isite2){ evdwlOld = sqrt(fractionOld1_i*fractionOld2_j)*evdwl; evdwl = sqrt(fraction1_i*fraction2_j)*evdwl; } else { evdwlOld = (sqrt(fractionOld1_i*fractionOld2_j) + sqrt(fractionOld2_i*fractionOld1_j))*evdwl; evdwl = (sqrt(fraction1_i*fraction2_j) + sqrt(fraction2_i*fraction1_j))*evdwl; } evdwlOld *= factor_lj; evdwl *= factor_lj; uCG_i += 0.5*evdwlOld; uCG[j] += 0.5*evdwlOld; uCGnew_i += 0.5*evdwl; uCGnew[j] += 0.5*evdwl; evdwl = evdwlOld; if (evflag) ev_tally(i,j,nlocal,newton_pair, evdwl,0.0,fpair,delx,dely,delz); } } uCG[i] += uCG_i; uCGnew[i] += uCGnew_i; f[i][0] += fx_i; f[i][1] += fy_i; f[i][2] += fz_i; } if (vflag_fdotr) virial_fdotr_compute(); memory->destroy(fractionOld1); memory->destroy(fractionOld2); memory->destroy(fraction1); memory->destroy(fraction2); } /* ---------------------------------------------------------------------- allocate all arrays ------------------------------------------------------------------------- */ void PairTableRX::allocate() { allocated = 1; const int nt = atom->ntypes + 1; memory->create(setflag,nt,nt,"pair:setflag"); memory->create(cutsq,nt,nt,"pair:cutsq"); memory->create(tabindex,nt,nt,"pair:tabindex"); memset(&setflag[0][0],0,nt*nt*sizeof(int)); memset(&cutsq[0][0],0,nt*nt*sizeof(double)); memset(&tabindex[0][0],0,nt*nt*sizeof(int)); } /* ---------------------------------------------------------------------- global settings ------------------------------------------------------------------------- */ void PairTableRX::settings(int narg, char **arg) { if (narg < 2) error->all(FLERR,"Illegal pair_style command"); // new settings if (strcmp(arg[0],"lookup") == 0) tabstyle = LOOKUP; else if (strcmp(arg[0],"linear") == 0) tabstyle = LINEAR; else if (strcmp(arg[0],"spline") == 0) tabstyle = SPLINE; else if (strcmp(arg[0],"bitmap") == 0) tabstyle = BITMAP; else error->all(FLERR,"Unknown table style in pair_style command"); tablength = force->inumeric(FLERR,arg[1]); if (tablength < 2) error->all(FLERR,"Illegal number of pair table entries"); // optional keywords // assert the tabulation is compatible with a specific long-range solver int iarg = 2; while (iarg < narg) { if (strcmp(arg[iarg],"ewald") == 0) ewaldflag = 1; else if (strcmp(arg[iarg],"pppm") == 0) pppmflag = 1; else if (strcmp(arg[iarg],"msm") == 0) msmflag = 1; else if (strcmp(arg[iarg],"dispersion") == 0) dispersionflag = 1; else if (strcmp(arg[iarg],"tip4p") == 0) tip4pflag = 1; else error->all(FLERR,"Illegal pair_style command"); iarg++; } // delete old tables, since cannot just change settings for (int m = 0; m < ntables; m++) free_table(&tables[m]); memory->sfree(tables); if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); memory->destroy(tabindex); } allocated = 0; ntables = 0; tables = NULL; } /* ---------------------------------------------------------------------- set coeffs for one or more type pairs ------------------------------------------------------------------------- */ void PairTableRX::coeff(int narg, char **arg) { if (narg != 6 && narg != 7) error->all(FLERR,"Illegal pair_coeff command"); if (!allocated) allocate(); bool rx_flag = false; for (int i = 0; i < modify->nfix; i++) if (strncmp(modify->fix[i]->style,"rx",2) == 0) rx_flag = true; if (!rx_flag) error->all(FLERR,"PairTableRX requires a fix rx command."); int ilo,ihi,jlo,jhi; force->bounds(arg[0],atom->ntypes,ilo,ihi); force->bounds(arg[1],atom->ntypes,jlo,jhi); int me; MPI_Comm_rank(world,&me); tables = (Table *) memory->srealloc(tables,(ntables+1)*sizeof(Table),"pair:tables"); Table *tb = &tables[ntables]; null_table(tb); if (me == 0) read_table(tb,arg[2],arg[3]); bcast_table(tb); nspecies = atom->nspecies_dpd; if(nspecies==0) error->all(FLERR,"There are no rx species specified."); int n; n = strlen(arg[3]) + 1; site1 = new char[n]; strcpy(site1,arg[4]); int ispecies; for (ispecies = 0; ispecies < nspecies; ispecies++){ if (strcmp(site1,&atom->dname[ispecies][0]) == 0) break; } if (ispecies == nspecies && strcmp(site1,"1fluid") != 0) error->all(FLERR,"Site1 name not recognized in pair coefficients"); n = strlen(arg[4]) + 1; site2 = new char[n]; strcpy(site2,arg[5]); for (ispecies = 0; ispecies < nspecies; ispecies++){ if (strcmp(site2,&atom->dname[ispecies][0]) == 0) break; } if (ispecies == nspecies && strcmp(site2,"1fluid") != 0) error->all(FLERR,"Site2 name not recognized in pair coefficients"); // set table cutoff if (narg == 7) tb->cut = force->numeric(FLERR,arg[6]); else if (tb->rflag) tb->cut = tb->rhi; else tb->cut = tb->rfile[tb->ninput-1]; // error check on table parameters // insure cutoff is within table // for BITMAP tables, file values can be in non-ascending order if (tb->ninput <= 1) error->one(FLERR,"Invalid pair table length"); double rlo,rhi; if (tb->rflag == 0) { rlo = tb->rfile[0]; rhi = tb->rfile[tb->ninput-1]; } else { rlo = tb->rlo; rhi = tb->rhi; } if (tb->cut <= rlo || tb->cut > rhi) error->all(FLERR,"Invalid pair table cutoff"); if (rlo <= 0.0) error->all(FLERR,"Invalid pair table cutoff"); // match = 1 if don't need to spline read-in tables // this is only the case if r values needed by final tables // exactly match r values read from file // for tabstyle SPLINE, always need to build spline tables tb->match = 0; if (tabstyle == LINEAR && tb->ninput == tablength && tb->rflag == RSQ && tb->rhi == tb->cut) tb->match = 1; if (tabstyle == BITMAP && tb->ninput == 1 << tablength && tb->rflag == BMP && tb->rhi == tb->cut) tb->match = 1; if (tb->rflag == BMP && tb->match == 0) error->all(FLERR,"Bitmapped table in file does not match requested table"); // spline read-in values and compute r,e,f vectors within table if (tb->match == 0) spline_table(tb); compute_table(tb); // store ptr to table in tabindex int count = 0; for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { tabindex[i][j] = ntables; setflag[i][j] = 1; count++; } } if (count == 0) error->all(FLERR,"Illegal pair_coeff command"); ntables++; { if ( strcmp(site1,"1fluid") == 0 ) isite1 = OneFluidValue; else { isite1 = nspecies; for (int k = 0; k < nspecies; k++){ if (strcmp(site1, atom->dname[k]) == 0){ isite1 = k; break; } } if (isite1 == nspecies) error->all(FLERR,"isite1 == nspecies"); } if ( strcmp(site2,"1fluid") == 0 ) isite2 = OneFluidValue; else { isite2 = nspecies; for (int k = 0; k < nspecies; k++){ if (strcmp(site2, atom->dname[k]) == 0){ isite2 = ispecies; break; } } if (isite2 == nspecies) error->all(FLERR,"isite2 == nspecies"); } } } /* ---------------------------------------------------------------------- init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ double PairTableRX::init_one(int i, int j) { if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); tabindex[j][i] = tabindex[i][j]; return tables[tabindex[i][j]].cut; } /* ---------------------------------------------------------------------- read a table section from a tabulated potential file only called by proc 0 this function sets these values in Table: ninput,rfile,efile,ffile,rflag,rlo,rhi,fpflag,fplo,fphi,ntablebits ------------------------------------------------------------------------- */ void PairTableRX::read_table(Table *tb, char *file, char *keyword) { char line[MAXLINE]; // open file FILE *fp = force->open_potential(file); if (fp == NULL) { char str[128]; sprintf(str,"Cannot open file %s",file); error->one(FLERR,str); } // loop until section found with matching keyword while (1) { if (fgets(line,MAXLINE,fp) == NULL) error->one(FLERR,"Did not find keyword in table file"); if (strspn(line," \t\n\r") == strlen(line)) continue; // blank line if (line[0] == '#') continue; // comment char *word = strtok(line," \t\n\r"); if (strcmp(word,keyword) == 0) break; // matching keyword fgets(line,MAXLINE,fp); // no match, skip section param_extract(tb,line); fgets(line,MAXLINE,fp); for (int i = 0; i < tb->ninput; i++) fgets(line,MAXLINE,fp); } // read args on 2nd line of section // allocate table arrays for file values fgets(line,MAXLINE,fp); param_extract(tb,line); memory->create(tb->rfile,tb->ninput,"pair:rfile"); memory->create(tb->efile,tb->ninput,"pair:efile"); memory->create(tb->ffile,tb->ninput,"pair:ffile"); // setup bitmap parameters for table to read in tb->ntablebits = 0; int masklo,maskhi,nmask,nshiftbits; if (tb->rflag == BMP) { while (1 << tb->ntablebits < tb->ninput) tb->ntablebits++; if (1 << tb->ntablebits != tb->ninput) error->one(FLERR,"Bitmapped table is incorrect length in table file"); init_bitmap(tb->rlo,tb->rhi,tb->ntablebits,masklo,maskhi,nmask,nshiftbits); } // read r,e,f table values from file // if rflag set, compute r // if rflag not set, use r from file int itmp; double rtmp; union_int_float_t rsq_lookup; fgets(line,MAXLINE,fp); for (int i = 0; i < tb->ninput; i++) { fgets(line,MAXLINE,fp); sscanf(line,"%d %lg %lg %lg",&itmp,&rtmp,&tb->efile[i],&tb->ffile[i]); if (tb->rflag == RLINEAR) rtmp = tb->rlo + (tb->rhi - tb->rlo)*i/(tb->ninput-1); else if (tb->rflag == RSQ) { rtmp = tb->rlo*tb->rlo + (tb->rhi*tb->rhi - tb->rlo*tb->rlo)*i/(tb->ninput-1); rtmp = sqrt(rtmp); } else if (tb->rflag == BMP) { rsq_lookup.i = i << nshiftbits; rsq_lookup.i |= masklo; if (rsq_lookup.f < tb->rlo*tb->rlo) { rsq_lookup.i = i << nshiftbits; rsq_lookup.i |= maskhi; } rtmp = sqrtf(rsq_lookup.f); } tb->rfile[i] = rtmp; } // close file fclose(fp); } /* ---------------------------------------------------------------------- broadcast read-in table info from proc 0 to other procs this function communicates these values in Table: ninput,rfile,efile,ffile,rflag,rlo,rhi,fpflag,fplo,fphi ------------------------------------------------------------------------- */ void PairTableRX::bcast_table(Table *tb) { MPI_Bcast(&tb->ninput,1,MPI_INT,0,world); int me; MPI_Comm_rank(world,&me); if (me > 0) { memory->create(tb->rfile,tb->ninput,"pair:rfile"); memory->create(tb->efile,tb->ninput,"pair:efile"); memory->create(tb->ffile,tb->ninput,"pair:ffile"); } MPI_Bcast(tb->rfile,tb->ninput,MPI_DOUBLE,0,world); MPI_Bcast(tb->efile,tb->ninput,MPI_DOUBLE,0,world); MPI_Bcast(tb->ffile,tb->ninput,MPI_DOUBLE,0,world); MPI_Bcast(&tb->rflag,1,MPI_INT,0,world); if (tb->rflag) { MPI_Bcast(&tb->rlo,1,MPI_DOUBLE,0,world); MPI_Bcast(&tb->rhi,1,MPI_DOUBLE,0,world); } MPI_Bcast(&tb->fpflag,1,MPI_INT,0,world); if (tb->fpflag) { MPI_Bcast(&tb->fplo,1,MPI_DOUBLE,0,world); MPI_Bcast(&tb->fphi,1,MPI_DOUBLE,0,world); } } /* ---------------------------------------------------------------------- build spline representation of e,f over entire range of read-in table this function sets these values in Table: e2file,f2file ------------------------------------------------------------------------- */ void PairTableRX::spline_table(Table *tb) { memory->create(tb->e2file,tb->ninput,"pair:e2file"); memory->create(tb->f2file,tb->ninput,"pair:f2file"); double ep0 = - tb->ffile[0]; double epn = - tb->ffile[tb->ninput-1]; spline(tb->rfile,tb->efile,tb->ninput,ep0,epn,tb->e2file); if (tb->fpflag == 0) { tb->fplo = (tb->ffile[1] - tb->ffile[0]) / (tb->rfile[1] - tb->rfile[0]); tb->fphi = (tb->ffile[tb->ninput-1] - tb->ffile[tb->ninput-2]) / (tb->rfile[tb->ninput-1] - tb->rfile[tb->ninput-2]); } double fp0 = tb->fplo; double fpn = tb->fphi; spline(tb->rfile,tb->ffile,tb->ninput,fp0,fpn,tb->f2file); } /* ---------------------------------------------------------------------- extract attributes from parameter line in table section format of line: N value R/RSQ/BITMAP lo hi FP fplo fphi N is required, other params are optional ------------------------------------------------------------------------- */ void PairTableRX::param_extract(Table *tb, char *line) { tb->ninput = 0; tb->rflag = NONE; tb->fpflag = 0; char *word = strtok(line," \t\n\r\f"); while (word) { if (strcmp(word,"N") == 0) { word = strtok(NULL," \t\n\r\f"); tb->ninput = atoi(word); } else if (strcmp(word,"R") == 0 || strcmp(word,"RSQ") == 0 || strcmp(word,"BITMAP") == 0) { if (strcmp(word,"R") == 0) tb->rflag = RLINEAR; else if (strcmp(word,"RSQ") == 0) tb->rflag = RSQ; else if (strcmp(word,"BITMAP") == 0) tb->rflag = BMP; word = strtok(NULL," \t\n\r\f"); tb->rlo = atof(word); word = strtok(NULL," \t\n\r\f"); tb->rhi = atof(word); } else if (strcmp(word,"FP") == 0) { tb->fpflag = 1; word = strtok(NULL," \t\n\r\f"); tb->fplo = atof(word); word = strtok(NULL," \t\n\r\f"); tb->fphi = atof(word); } else { printf("WORD: %s\n",word); error->one(FLERR,"Invalid keyword in pair table parameters"); } word = strtok(NULL," \t\n\r\f"); } if (tb->ninput == 0) error->one(FLERR,"Pair table parameters did not set N"); } /* ---------------------------------------------------------------------- compute r,e,f vectors from splined values ------------------------------------------------------------------------- */ void PairTableRX::compute_table(Table *tb) { int tlm1 = tablength-1; // inner = inner table bound // cut = outer table bound // delta = table spacing in rsq for N-1 bins double inner; if (tb->rflag) inner = tb->rlo; else inner = tb->rfile[0]; tb->innersq = double(inner)*double(inner); tb->delta = double(tb->cut*tb->cut - double(tb->innersq)) / double(tlm1); tb->invdelta = 1.0/double(tb->delta); // direct lookup tables // N-1 evenly spaced bins in rsq from inner to cut // e,f = value at midpt of bin // e,f are N-1 in length since store 1 value at bin midpt // f is converted to f/r when stored in f[i] // e,f are never a match to read-in values, always computed via spline interp if (tabstyle == LOOKUP) { memory->create(tb->e,tlm1,"pair:e"); memory->create(tb->f,tlm1,"pair:f"); double r,rsq; for (int i = 0; i < tlm1; i++) { rsq = tb->innersq + (i+0.5)*tb->delta; r = sqrt(rsq); tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r)/r; } } // linear tables // N-1 evenly spaced bins in rsq from inner to cut // rsq,e,f = value at lower edge of bin // de,df values = delta from lower edge to upper edge of bin // rsq,e,f are N in length so de,df arrays can compute difference // f is converted to f/r when stored in f[i] // e,f can match read-in values, else compute via spline interp if (tabstyle == LINEAR) { memory->create(tb->rsq,tablength,"pair:rsq"); memory->create(tb->e,tablength,"pair:e"); memory->create(tb->f,tablength,"pair:f"); memory->create(tb->de,tlm1,"pair:de"); memory->create(tb->df,tlm1,"pair:df"); double r,rsq; for (int i = 0; i < tablength; i++) { rsq = tb->innersq + i*tb->delta; r = sqrt(rsq); tb->rsq[i] = rsq; if (tb->match) { tb->e[i] = tb->efile[i]; tb->f[i] = tb->ffile[i]/r; } else { tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r)/r; } } for (int i = 0; i < tlm1; i++) { tb->de[i] = tb->e[i+1] - tb->e[i]; tb->df[i] = tb->f[i+1] - tb->f[i]; } } // cubic spline tables // N-1 evenly spaced bins in rsq from inner to cut // rsq,e,f = value at lower edge of bin // e2,f2 = spline coefficient for each bin // rsq,e,f,e2,f2 are N in length so have N-1 spline bins // f is converted to f/r after e is splined // e,f can match read-in values, else compute via spline interp if (tabstyle == SPLINE) { memory->create(tb->rsq,tablength,"pair:rsq"); memory->create(tb->e,tablength,"pair:e"); memory->create(tb->f,tablength,"pair:f"); memory->create(tb->e2,tablength,"pair:e2"); memory->create(tb->f2,tablength,"pair:f2"); tb->deltasq6 = tb->delta*tb->delta / 6.0; double r,rsq; for (int i = 0; i < tablength; i++) { rsq = tb->innersq + i*tb->delta; r = sqrt(rsq); tb->rsq[i] = rsq; if (tb->match) { tb->e[i] = tb->efile[i]; tb->f[i] = tb->ffile[i]/r; } else { tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r); } } // ep0,epn = dh/dg at inner and at cut // h(r) = e(r) and g(r) = r^2 // dh/dg = (de/dr) / 2r = -f/2r double ep0 = - tb->f[0] / (2.0 * sqrt(tb->innersq)); double epn = - tb->f[tlm1] / (2.0 * tb->cut); spline(tb->rsq,tb->e,tablength,ep0,epn,tb->e2); // fp0,fpn = dh/dg at inner and at cut // h(r) = f(r)/r and g(r) = r^2 // dh/dg = (1/r df/dr - f/r^2) / 2r // dh/dg in secant approx = (f(r2)/r2 - f(r1)/r1) / (g(r2) - g(r1)) double fp0,fpn; double secant_factor = 0.1; if (tb->fpflag) fp0 = (tb->fplo/sqrt(tb->innersq) - tb->f[0]/tb->innersq) / (2.0 * sqrt(tb->innersq)); else { double rsq1 = tb->innersq; double rsq2 = rsq1 + secant_factor*tb->delta; fp0 = (splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,sqrt(rsq2)) / sqrt(rsq2) - tb->f[0] / sqrt(rsq1)) / (secant_factor*tb->delta); } if (tb->fpflag && tb->cut == tb->rfile[tb->ninput-1]) fpn = (tb->fphi/tb->cut - tb->f[tlm1]/(tb->cut*tb->cut)) / (2.0 * tb->cut); else { double rsq2 = tb->cut * tb->cut; double rsq1 = rsq2 - secant_factor*tb->delta; fpn = (tb->f[tlm1] / sqrt(rsq2) - splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,sqrt(rsq1)) / sqrt(rsq1)) / (secant_factor*tb->delta); } for (int i = 0; i < tablength; i++) tb->f[i] /= sqrt(tb->rsq[i]); spline(tb->rsq,tb->f,tablength,fp0,fpn,tb->f2); } // bitmapped linear tables // 2^N bins from inner to cut, spaced in bitmapped manner // f is converted to f/r when stored in f[i] // e,f can match read-in values, else compute via spline interp if (tabstyle == BITMAP) { double r; union_int_float_t rsq_lookup; int masklo,maskhi; // linear lookup tables of length ntable = 2^n // stored value = value at lower edge of bin init_bitmap(inner,tb->cut,tablength,masklo,maskhi,tb->nmask,tb->nshiftbits); int ntable = 1 << tablength; int ntablem1 = ntable - 1; memory->create(tb->rsq,ntable,"pair:rsq"); memory->create(tb->e,ntable,"pair:e"); memory->create(tb->f,ntable,"pair:f"); memory->create(tb->de,ntable,"pair:de"); memory->create(tb->df,ntable,"pair:df"); memory->create(tb->drsq,ntable,"pair:drsq"); union_int_float_t minrsq_lookup; minrsq_lookup.i = 0 << tb->nshiftbits; minrsq_lookup.i |= maskhi; for (int i = 0; i < ntable; i++) { rsq_lookup.i = i << tb->nshiftbits; rsq_lookup.i |= masklo; if (rsq_lookup.f < tb->innersq) { rsq_lookup.i = i << tb->nshiftbits; rsq_lookup.i |= maskhi; } r = sqrtf(rsq_lookup.f); tb->rsq[i] = rsq_lookup.f; if (tb->match) { tb->e[i] = tb->efile[i]; tb->f[i] = tb->ffile[i]/r; } else { tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r)/r; } minrsq_lookup.f = MIN(minrsq_lookup.f,rsq_lookup.f); } tb->innersq = minrsq_lookup.f; for (int i = 0; i < ntablem1; i++) { tb->de[i] = tb->e[i+1] - tb->e[i]; tb->df[i] = tb->f[i+1] - tb->f[i]; tb->drsq[i] = 1.0/(tb->rsq[i+1] - tb->rsq[i]); } // get the delta values for the last table entries // tables are connected periodically between 0 and ntablem1 tb->de[ntablem1] = tb->e[0] - tb->e[ntablem1]; tb->df[ntablem1] = tb->f[0] - tb->f[ntablem1]; tb->drsq[ntablem1] = 1.0/(tb->rsq[0] - tb->rsq[ntablem1]); // get the correct delta values at itablemax // smallest r is in bin itablemin // largest r is in bin itablemax, which is itablemin-1, // or ntablem1 if itablemin=0 // deltas at itablemax only needed if corresponding rsq < cut*cut // if so, compute deltas between rsq and cut*cut // if tb->match, data at cut*cut is unavailable, so we'll take // deltas at itablemax-1 as a good approximation double e_tmp,f_tmp; int itablemin = minrsq_lookup.i & tb->nmask; itablemin >>= tb->nshiftbits; int itablemax = itablemin - 1; if (itablemin == 0) itablemax = ntablem1; int itablemaxm1 = itablemax - 1; if (itablemax == 0) itablemaxm1 = ntablem1; rsq_lookup.i = itablemax << tb->nshiftbits; rsq_lookup.i |= maskhi; if (rsq_lookup.f < tb->cut*tb->cut) { if (tb->match) { tb->de[itablemax] = tb->de[itablemaxm1]; tb->df[itablemax] = tb->df[itablemaxm1]; tb->drsq[itablemax] = tb->drsq[itablemaxm1]; } else { rsq_lookup.f = tb->cut*tb->cut; r = sqrtf(rsq_lookup.f); e_tmp = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); f_tmp = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r)/r; tb->de[itablemax] = e_tmp - tb->e[itablemax]; tb->df[itablemax] = f_tmp - tb->f[itablemax]; tb->drsq[itablemax] = 1.0/(rsq_lookup.f - tb->rsq[itablemax]); } } } } /* ---------------------------------------------------------------------- set all ptrs in a table to NULL, so can be freed safely ------------------------------------------------------------------------- */ void PairTableRX::null_table(Table *tb) { tb->rfile = tb->efile = tb->ffile = NULL; tb->e2file = tb->f2file = NULL; tb->rsq = tb->drsq = tb->e = tb->de = NULL; tb->f = tb->df = tb->e2 = tb->f2 = NULL; } /* ---------------------------------------------------------------------- free all arrays in a table ------------------------------------------------------------------------- */ void PairTableRX::free_table(Table *tb) { memory->destroy(tb->rfile); memory->destroy(tb->efile); memory->destroy(tb->ffile); memory->destroy(tb->e2file); memory->destroy(tb->f2file); memory->destroy(tb->rsq); memory->destroy(tb->drsq); memory->destroy(tb->e); memory->destroy(tb->de); memory->destroy(tb->f); memory->destroy(tb->df); memory->destroy(tb->e2); memory->destroy(tb->f2); } /* ---------------------------------------------------------------------- spline and splint routines modified from Numerical Recipes ------------------------------------------------------------------------- */ void PairTableRX::spline(double *x, double *y, int n, double yp1, double ypn, double *y2) { int i,k; double p,qn,sig,un; double *u = new double[n]; if (yp1 > 0.99e30) y2[0] = u[0] = 0.0; else { y2[0] = -0.5; u[0] = (3.0/(x[1]-x[0])) * ((y[1]-y[0]) / (x[1]-x[0]) - yp1); } for (i = 1; i < n-1; i++) { sig = (x[i]-x[i-1]) / (x[i+1]-x[i-1]); p = sig*y2[i-1] + 2.0; y2[i] = (sig-1.0) / p; u[i] = (y[i+1]-y[i]) / (x[i+1]-x[i]) - (y[i]-y[i-1]) / (x[i]-x[i-1]); u[i] = (6.0*u[i] / (x[i+1]-x[i-1]) - sig*u[i-1]) / p; } if (ypn > 0.99e30) qn = un = 0.0; else { qn = 0.5; un = (3.0/(x[n-1]-x[n-2])) * (ypn - (y[n-1]-y[n-2]) / (x[n-1]-x[n-2])); } y2[n-1] = (un-qn*u[n-2]) / (qn*y2[n-2] + 1.0); for (k = n-2; k >= 0; k--) y2[k] = y2[k]*y2[k+1] + u[k]; delete [] u; } /* ---------------------------------------------------------------------- */ double PairTableRX::splint(double *xa, double *ya, double *y2a, int n, double x) { int klo,khi,k; double h,b,a,y; klo = 0; khi = n-1; while (khi-klo > 1) { k = (khi+klo) >> 1; if (xa[k] > x) khi = k; else klo = k; } h = xa[khi]-xa[klo]; a = (xa[khi]-x) / h; b = (x-xa[klo]) / h; y = a*ya[klo] + b*ya[khi] + ((a*a*a-a)*y2a[klo] + (b*b*b-b)*y2a[khi]) * (h*h)/6.0; return y; } /* ---------------------------------------------------------------------- proc 0 writes to restart file ------------------------------------------------------------------------- */ void PairTableRX::write_restart(FILE *fp) { write_restart_settings(fp); } /* ---------------------------------------------------------------------- proc 0 reads from restart file, bcasts ------------------------------------------------------------------------- */ void PairTableRX::read_restart(FILE *fp) { read_restart_settings(fp); allocate(); } /* ---------------------------------------------------------------------- proc 0 writes to restart file ------------------------------------------------------------------------- */ void PairTableRX::write_restart_settings(FILE *fp) { fwrite(&tabstyle,sizeof(int),1,fp); fwrite(&tablength,sizeof(int),1,fp); fwrite(&ewaldflag,sizeof(int),1,fp); fwrite(&pppmflag,sizeof(int),1,fp); fwrite(&msmflag,sizeof(int),1,fp); fwrite(&dispersionflag,sizeof(int),1,fp); fwrite(&tip4pflag,sizeof(int),1,fp); } /* ---------------------------------------------------------------------- proc 0 reads from restart file, bcasts ------------------------------------------------------------------------- */ void PairTableRX::read_restart_settings(FILE *fp) { if (comm->me == 0) { fread(&tabstyle,sizeof(int),1,fp); fread(&tablength,sizeof(int),1,fp); fread(&ewaldflag,sizeof(int),1,fp); fread(&pppmflag,sizeof(int),1,fp); fread(&msmflag,sizeof(int),1,fp); fread(&dispersionflag,sizeof(int),1,fp); fread(&tip4pflag,sizeof(int),1,fp); } MPI_Bcast(&tabstyle,1,MPI_INT,0,world); MPI_Bcast(&tablength,1,MPI_INT,0,world); MPI_Bcast(&ewaldflag,1,MPI_INT,0,world); MPI_Bcast(&pppmflag,1,MPI_INT,0,world); MPI_Bcast(&msmflag,1,MPI_INT,0,world); MPI_Bcast(&dispersionflag,1,MPI_INT,0,world); MPI_Bcast(&tip4pflag,1,MPI_INT,0,world); } /* ---------------------------------------------------------------------- */ double PairTableRX::single(int i, int j, int itype, int jtype, double rsq, double factor_coul, double factor_lj, double &fforce) { int itable; double fraction,value,a,b,phi; int tlm1 = tablength - 1; Table *tb = &tables[tabindex[itype][jtype]]; double fraction1_i, fraction1_j; double fraction2_i, fraction2_j; double fractionOld1_i, fractionOld1_j; double fractionOld2_i, fractionOld2_j; fraction = 0.0; a = 0.0; b = 0.0; getParams(i,fractionOld1_i,fractionOld2_i,fraction1_i,fraction2_i); getParams(j,fractionOld1_j,fractionOld2_j,fraction1_j,fraction2_j); if (rsq < tb->innersq) error->one(FLERR,"Pair distance < table inner cutoff"); if (tabstyle == LOOKUP) { itable = static_cast ((rsq-tb->innersq) * tb->invdelta); if (itable >= tlm1) error->one(FLERR,"Pair distance > table outer cutoff"); fforce = factor_lj * tb->f[itable]; } else if (tabstyle == LINEAR) { itable = static_cast ((rsq-tb->innersq) * tb->invdelta); if (itable >= tlm1) error->one(FLERR,"Pair distance > table outer cutoff"); fraction = (rsq - tb->rsq[itable]) * tb->invdelta; value = tb->f[itable] + fraction*tb->df[itable]; fforce = factor_lj * value; } else if (tabstyle == SPLINE) { itable = static_cast ((rsq-tb->innersq) * tb->invdelta); if (itable >= tlm1) error->one(FLERR,"Pair distance > table outer cutoff"); b = (rsq - tb->rsq[itable]) * tb->invdelta; a = 1.0 - b; value = a * tb->f[itable] + b * tb->f[itable+1] + ((a*a*a-a)*tb->f2[itable] + (b*b*b-b)*tb->f2[itable+1]) * tb->deltasq6; fforce = factor_lj * value; } else { union_int_float_t rsq_lookup; rsq_lookup.f = rsq; itable = rsq_lookup.i & tb->nmask; itable >>= tb->nshiftbits; fraction = (rsq_lookup.f - tb->rsq[itable]) * tb->drsq[itable]; value = tb->f[itable] + fraction*tb->df[itable]; fforce = factor_lj * value; } if (isite1 == isite2) fforce = sqrt(fraction1_i*fraction2_j)*fforce; else fforce = (sqrt(fraction1_i*fraction2_j) + sqrt(fraction2_i*fraction1_j))*fforce; if (tabstyle == LOOKUP) phi = tb->e[itable]; else if (tabstyle == LINEAR || tabstyle == BITMAP) phi = tb->e[itable] + fraction*tb->de[itable]; else phi = a * tb->e[itable] + b * tb->e[itable+1] + ((a*a*a-a)*tb->e2[itable] + (b*b*b-b)*tb->e2[itable+1]) * tb->deltasq6; if (isite1 == isite2) phi = sqrt(fraction1_i*fraction2_j)*phi; else phi = (sqrt(fraction1_i*fraction2_j) + sqrt(fraction2_i*fraction1_j))*phi; return factor_lj*phi; } /* ---------------------------------------------------------------------- return the Coulomb cutoff for tabled potentials called by KSpace solvers which require that all pairwise cutoffs be the same loop over all tables not just those indexed by tabindex[i][j] since no way to know which tables are active since pair::init() not yet called ------------------------------------------------------------------------- */ void *PairTableRX::extract(const char *str, int &dim) { if (strcmp(str,"cut_coul") != 0) return NULL; if (ntables == 0) error->all(FLERR,"All pair coeffs are not set"); double cut_coul = tables[0].cut; for (int m = 1; m < ntables; m++) if (tables[m].cut != cut_coul) error->all(FLERR,"Pair table cutoffs must all be equal to use with KSpace"); dim = 0; return &tables[0].cut; } /* ---------------------------------------------------------------------- */ void PairTableRX::getParams(int id, double &fractionOld1, double &fractionOld2, double &fraction1, double &fraction2) { double nTotal = 0.0; double nTotalOld = 0.0; for (int ispecies = 0; ispecies < nspecies; ++ispecies){ nTotal += atom->dvector[ispecies][id]; nTotalOld += atom->dvector[ispecies+nspecies][id]; } if(nTotal < 1e-8 || nTotalOld < 1e-8) error->all(FLERR,"The number of molecules in CG particle is less than 1e-8."); if (isOneFluid(isite1) == false){ fractionOld1 = atom->dvector[isite1+nspecies][id]/nTotalOld; fraction1 = atom->dvector[isite1][id]/nTotal; } if (isOneFluid(isite2) == false){ fractionOld2 = atom->dvector[isite2+nspecies][id]/nTotalOld; fraction2 = atom->dvector[isite2][id]/nTotal; } if (isOneFluid(isite1) || isOneFluid(isite2)){ double fractionOld = 0.0; double fraction = 0.0; for (int ispecies = 0; ispecies < nspecies; ispecies++){ if (isite1 == ispecies || isite2 == ispecies) continue; fractionOld += atom->dvector[ispecies+nspecies][id]/nTotalOld; fraction += atom->dvector[ispecies][id]/nTotal; } if(isOneFluid(isite1)){ fractionOld1 = fractionOld; fraction1 = fraction; } if(isOneFluid(isite2)){ fractionOld2 = fractionOld; fraction2 = fraction; } } } diff --git a/src/USER-INTEL/dihedral_charmm_intel.cpp b/src/USER-INTEL/dihedral_charmm_intel.cpp index 7e93e319d..c07c22661 100644 --- a/src/USER-INTEL/dihedral_charmm_intel.cpp +++ b/src/USER-INTEL/dihedral_charmm_intel.cpp @@ -1,1001 +1,1001 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: W. Michael Brown (Intel) ------------------------------------------------------------------------- */ -#include "mpi.h" -#include "math.h" +#include +#include #include "dihedral_charmm_intel.h" #include "atom.h" #include "comm.h" #include "memory.h" #include "neighbor.h" #include "domain.h" #include "force.h" #include "pair.h" #include "update.h" #include "error.h" #ifdef LMP_USE_AVXCD #if (__INTEL_COMPILER_BUILD_DATE > 20160414) #define LMP_USE_AVXCD_DHC #endif #endif #ifdef LMP_USE_AVXCD_DHC #include "intel_simd.h" using namespace ip_simd; #endif #include "suffix.h" using namespace LAMMPS_NS; #define PTOLERANCE (flt_t)1.05 #define MTOLERANCE (flt_t)-1.05 typedef struct { int a,b,c,d,t; } int5_t; /* ---------------------------------------------------------------------- */ DihedralCharmmIntel::DihedralCharmmIntel(class LAMMPS *lmp) : DihedralCharmm(lmp) { suffix_flag |= Suffix::INTEL; } /* ---------------------------------------------------------------------- */ void DihedralCharmmIntel::compute(int eflag, int vflag) { #ifdef _LMP_INTEL_OFFLOAD if (_use_base) { DihedralCharmm::compute(eflag, vflag); return; } #endif if (fix->precision() == FixIntel::PREC_MODE_MIXED) compute(eflag, vflag, fix->get_mixed_buffers(), force_const_single); else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) compute(eflag, vflag, fix->get_double_buffers(), force_const_double); else compute(eflag, vflag, fix->get_single_buffers(), force_const_single); } /* ---------------------------------------------------------------------- */ template void DihedralCharmmIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { if (eflag || vflag) { ev_setup(eflag,vflag); } else evflag = 0; // insure pair->ev_tally() will use 1-4 virial contribution if (weightflag && vflag_global == 2) force->pair->vflag_either = force->pair->vflag_global = 1; if (evflag) { if (eflag) { if (force->newton_bond) eval<1,1,1>(vflag, buffers, fc); else eval<1,1,0>(vflag, buffers, fc); } else { if (force->newton_bond) eval<1,0,1>(vflag, buffers, fc); else eval<1,0,0>(vflag, buffers, fc); } } else { if (force->newton_bond) eval<0,0,1>(vflag, buffers, fc); else eval<0,0,0>(vflag, buffers, fc); } } #ifndef LMP_USE_AVXCD_DHC template void DihedralCharmmIntel::eval(const int vflag, IntelBuffers *buffers, const ForceConst &fc) { const int inum = neighbor->ndihedrallist; if (inum == 0) return; ATOM_T * _noalias const x = buffers->get_x(0); flt_t * _noalias const q = buffers->get_q(0); const int nlocal = atom->nlocal; const int nall = nlocal + atom->nghost; int f_stride; if (NEWTON_BOND) f_stride = buffers->get_stride(nall); else f_stride = buffers->get_stride(nlocal); int tc; FORCE_T * _noalias f_start; acc_t * _noalias ev_global; IP_PRE_get_buffers(0, buffers, fix, tc, f_start, ev_global); const int nthreads = tc; acc_t oedihedral, ov0, ov1, ov2, ov3, ov4, ov5; acc_t oevdwl, oecoul, opv0, opv1, opv2, opv3, opv4, opv5; if (EVFLAG) { if (EFLAG) oevdwl = oecoul = oedihedral = (acc_t)0.0; if (vflag) { ov0 = ov1 = ov2 = ov3 = ov4 = ov5 = (acc_t)0.0; opv0 = opv1 = opv2 = opv3 = opv4 = opv5 = (acc_t)0.0; } } #if defined(_OPENMP) #pragma omp parallel default(none) \ shared(f_start,f_stride,fc) \ reduction(+:oevdwl,oecoul,oedihedral,ov0,ov1,ov2,ov3,ov4,ov5, \ opv0,opv1,opv2,opv3,opv4,opv5) #endif { int nfrom, nto, tid; IP_PRE_omp_range_id(nfrom, nto, tid, inum, nthreads); FORCE_T * _noalias const f = f_start + (tid * f_stride); if (fix->need_zero(tid)) memset(f, 0, f_stride * sizeof(FORCE_T)); const int5_t * _noalias const dihedrallist = (int5_t *) neighbor->dihedrallist[0]; const flt_t qqrd2e = force->qqrd2e; acc_t sedihedral, sv0, sv1, sv2, sv3, sv4, sv5; acc_t sevdwl, secoul, spv0, spv1, spv2, spv3, spv4, spv5; if (EVFLAG) { if (EFLAG) sevdwl = secoul = sedihedral = (acc_t)0.0; if (vflag) { sv0 = sv1 = sv2 = sv3 = sv4 = sv5 = (acc_t)0.0; spv0 = spv1 = spv2 = spv3 = spv4 = spv5 = (acc_t)0.0; } } #if defined(LMP_SIMD_COMPILER_TEST) #pragma vector aligned #pragma simd reduction(+:sedihedral, sevdwl, secoul, sv0, sv1, sv2, \ sv3, sv4, sv5, spv0, spv1, spv2, spv3, spv4, spv5) #endif for (int n = nfrom; n < nto; n++) { const int i1 = dihedrallist[n].a; const int i2 = dihedrallist[n].b; const int i3 = dihedrallist[n].c; const int i4 = dihedrallist[n].d; const int type = dihedrallist[n].t; // 1st bond const flt_t vb1x = x[i1].x - x[i2].x; const flt_t vb1y = x[i1].y - x[i2].y; const flt_t vb1z = x[i1].z - x[i2].z; const int itype = x[i1].w; // 2nd bond const flt_t vb2xm = x[i2].x - x[i3].x; const flt_t vb2ym = x[i2].y - x[i3].y; const flt_t vb2zm = x[i2].z - x[i3].z; // 3rd bond const flt_t vb3x = x[i4].x - x[i3].x; const flt_t vb3y = x[i4].y - x[i3].y; const flt_t vb3z = x[i4].z - x[i3].z; const int jtype = x[i4].w; // 1-4 const flt_t delx = x[i1].x - x[i4].x; const flt_t dely = x[i1].y - x[i4].y; const flt_t delz = x[i1].z - x[i4].z; // c,s calculation const flt_t ax = vb1y*vb2zm - vb1z*vb2ym; const flt_t ay = vb1z*vb2xm - vb1x*vb2zm; const flt_t az = vb1x*vb2ym - vb1y*vb2xm; const flt_t bx = vb3y*vb2zm - vb3z*vb2ym; const flt_t by = vb3z*vb2xm - vb3x*vb2zm; const flt_t bz = vb3x*vb2ym - vb3y*vb2xm; const flt_t rasq = ax*ax + ay*ay + az*az; const flt_t rbsq = bx*bx + by*by + bz*bz; const flt_t rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm; const flt_t rg = sqrt(rgsq); flt_t rginv, ra2inv, rb2inv; rginv = ra2inv = rb2inv = (flt_t)0.0; if (rg > 0) rginv = (flt_t)1.0/rg; if (rasq > 0) ra2inv = (flt_t)1.0/rasq; if (rbsq > 0) rb2inv = (flt_t)1.0/rbsq; const flt_t rabinv = sqrt(ra2inv*rb2inv); flt_t c = (ax*bx + ay*by + az*bz)*rabinv; const flt_t s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z); // error check #ifndef LMP_SIMD_COMPILER_TEST if (c > PTOLERANCE || c < MTOLERANCE) { int me = comm->me; if (screen) { char str[128]; sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, me,tid,update->ntimestep, atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); error->warning(FLERR,str,0); fprintf(screen," 1st atom: %d %g %g %g\n", me,x[i1].x,x[i1].y,x[i1].z); fprintf(screen," 2nd atom: %d %g %g %g\n", me,x[i2].x,x[i2].y,x[i2].z); fprintf(screen," 3rd atom: %d %g %g %g\n", me,x[i3].x,x[i3].y,x[i3].z); fprintf(screen," 4th atom: %d %g %g %g\n", me,x[i4].x,x[i4].y,x[i4].z); } } #endif if (c > (flt_t)1.0) c = (flt_t)1.0; if (c < (flt_t)-1.0) c = (flt_t)-1.0; const flt_t tcos_shift = fc.bp[type].cos_shift; const flt_t tsin_shift = fc.bp[type].sin_shift; const flt_t tk = fc.bp[type].k; const int m = fc.bp[type].multiplicity; flt_t p = (flt_t)1.0; flt_t ddf1, df1; ddf1 = df1 = (flt_t)0.0; for (int i = 0; i < m; i++) { ddf1 = p*c - df1*s; df1 = p*s + df1*c; p = ddf1; } p = p*tcos_shift + df1*tsin_shift; df1 = df1*tcos_shift - ddf1*tsin_shift; df1 *= -m; p += (flt_t)1.0; if (m == 0) { p = (flt_t)1.0 + tcos_shift; df1 = (flt_t)0.0; } const flt_t fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm; const flt_t hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm; const flt_t fga = fg*ra2inv*rginv; const flt_t hgb = hg*rb2inv*rginv; const flt_t gaa = -ra2inv*rg; const flt_t gbb = rb2inv*rg; const flt_t dtfx = gaa*ax; const flt_t dtfy = gaa*ay; const flt_t dtfz = gaa*az; const flt_t dtgx = fga*ax - hgb*bx; const flt_t dtgy = fga*ay - hgb*by; const flt_t dtgz = fga*az - hgb*bz; const flt_t dthx = gbb*bx; const flt_t dthy = gbb*by; const flt_t dthz = gbb*bz; const flt_t df = -tk * df1; const flt_t sx2 = df*dtgx; const flt_t sy2 = df*dtgy; const flt_t sz2 = df*dtgz; flt_t f1x = df*dtfx; flt_t f1y = df*dtfy; flt_t f1z = df*dtfz; const flt_t f2x = sx2 - f1x; const flt_t f2y = sy2 - f1y; const flt_t f2z = sz2 - f1z; flt_t f4x = df*dthx; flt_t f4y = df*dthy; flt_t f4z = df*dthz; const flt_t f3x = -sx2 - f4x; const flt_t f3y = -sy2 - f4y; const flt_t f3z = -sz2 - f4z; if (EVFLAG) { flt_t deng; if (EFLAG) deng = tk * p; IP_PRE_ev_tally_dihed(EFLAG, eatom, vflag, deng, i1, i2, i3, i4, f1x, f1y, f1z, f3x, f3y, f3z, f4x, f4y, f4z, vb1x, vb1y, vb1z, -vb2xm, -vb2ym, -vb2zm, vb3x, vb3y, vb3z, sedihedral, f, NEWTON_BOND, nlocal, sv0, sv1, sv2, sv3, sv4, sv5); } #if defined(LMP_SIMD_COMPILER_TEST) #pragma simdoff #endif { if (NEWTON_BOND || i2 < nlocal) { f[i2].x += f2x; f[i2].y += f2y; f[i2].z += f2z; } if (NEWTON_BOND || i3 < nlocal) { f[i3].x += f3x; f[i3].y += f3y; f[i3].z += f3z; } } // 1-4 LJ and Coulomb interactions // tally energy/virial in pair, using newton_bond as newton flag const flt_t tweight = fc.weight[type]; const flt_t rsq = delx*delx + dely*dely + delz*delz; const flt_t r2inv = (flt_t)1.0/rsq; const flt_t r6inv = r2inv*r2inv*r2inv; flt_t forcecoul; if (implicit) forcecoul = qqrd2e * q[i1]*q[i4]*r2inv; else forcecoul = qqrd2e * q[i1]*q[i4]*sqrt(r2inv); const flt_t forcelj = r6inv * (fc.ljp[itype][jtype].lj1*r6inv - fc.ljp[itype][jtype].lj2); const flt_t fpair = tweight * (forcelj+forcecoul)*r2inv; if (NEWTON_BOND || i1 < nlocal) { f1x += delx*fpair; f1y += dely*fpair; f1z += delz*fpair; } if (NEWTON_BOND || i4 < nlocal) { f4x -= delx*fpair; f4y -= dely*fpair; f4z -= delz*fpair; } if (EVFLAG) { flt_t ev_pre = (flt_t)0; if (NEWTON_BOND || i1 < nlocal) ev_pre += (flt_t)0.5; if (NEWTON_BOND || i4 < nlocal) ev_pre += (flt_t)0.5; if (EFLAG) { flt_t ecoul, evdwl; ecoul = tweight * forcecoul; evdwl = tweight * r6inv * (fc.ljp[itype][jtype].lj3*r6inv - fc.ljp[itype][jtype].lj4); secoul += ev_pre * ecoul; sevdwl += ev_pre * evdwl; if (eatom) { evdwl *= (flt_t)0.5; evdwl += (flt_t)0.5 * ecoul; if (NEWTON_BOND || i1 < nlocal) f[i1].w += evdwl; if (NEWTON_BOND || i4 < nlocal) f[i4].w += evdwl; } } // IP_PRE_ev_tally_nbor(vflag, ev_pre, fpair, // delx, dely, delz); if (vflag) { spv0 += ev_pre * delx * delx * fpair; spv1 += ev_pre * dely * dely * fpair; spv2 += ev_pre * delz * delz * fpair; spv3 += ev_pre * delx * dely * fpair; spv4 += ev_pre * delx * delz * fpair; spv5 += ev_pre * dely * delz * fpair; } } // apply force to each of 4 atoms #if defined(LMP_SIMD_COMPILER_TEST) #pragma simdoff #endif { if (NEWTON_BOND || i1 < nlocal) { f[i1].x += f1x; f[i1].y += f1y; f[i1].z += f1z; } if (NEWTON_BOND || i4 < nlocal) { f[i4].x += f4x; f[i4].y += f4y; f[i4].z += f4z; } } } // for n if (EVFLAG) { if (EFLAG) { oedihedral += sedihedral; oecoul += secoul; oevdwl += sevdwl; } if (vflag) { ov0 += sv0; ov1 += sv1; ov2 += sv2; ov3 += sv3; ov4 += sv4; ov5 += sv5; opv0 += spv0; opv1 += spv1; opv2 += spv2; opv3 += spv3; opv4 += spv4; opv5 += spv5; } } } // omp parallel if (EVFLAG) { if (EFLAG) { energy += oedihedral; force->pair->eng_vdwl += oevdwl; force->pair->eng_coul += oecoul; } if (vflag) { virial[0] += ov0; virial[1] += ov1; virial[2] += ov2; virial[3] += ov3; virial[4] += ov4; virial[5] += ov5; force->pair->virial[0] += opv0; force->pair->virial[1] += opv1; force->pair->virial[2] += opv2; force->pair->virial[3] += opv3; force->pair->virial[4] += opv4; force->pair->virial[5] += opv5; } } fix->set_reduce_flag(); } #else /* ---------------------------------------------------------------------- Vector intrinsics are temporarily being used for the Stillinger-Weber potential to allow for advanced features in the AVX512 instruction set to be exploited on early hardware. We hope to see compiler improvements for AVX512 that will eliminate this requirement, so it is not recommended to develop code based on the intrinsics implementation. Please e-mail the authors for more details. ------------------------------------------------------------------------- */ template void DihedralCharmmIntel::eval(const int vflag, IntelBuffers *buffers, const ForceConst &fc) { typedef typename SIMD_type::SIMD_vec SIMD_flt_t; typedef typename SIMD_type::SIMD_vec SIMD_acc_t; const int swidth = SIMD_type::width(); const int inum = neighbor->ndihedrallist; if (inum == 0) return; ATOM_T * _noalias const x = buffers->get_x(0); flt_t * _noalias const q = buffers->get_q(0); const int nlocal = atom->nlocal; const int nall = nlocal + atom->nghost; int f_stride; if (NEWTON_BOND) f_stride = buffers->get_stride(nall); else f_stride = buffers->get_stride(nlocal); int tc; FORCE_T * _noalias f_start; acc_t * _noalias ev_global; IP_PRE_get_buffers(0, buffers, fix, tc, f_start, ev_global); const int nthreads = tc; acc_t oedihedral, ov0, ov1, ov2, ov3, ov4, ov5; acc_t oevdwl, oecoul, opv0, opv1, opv2, opv3, opv4, opv5; if (EVFLAG) { if (EFLAG) oevdwl = oecoul = oedihedral = (acc_t)0.0; if (vflag) { ov0 = ov1 = ov2 = ov3 = ov4 = ov5 = (acc_t)0.0; opv0 = opv1 = opv2 = opv3 = opv4 = opv5 = (acc_t)0.0; } } #if defined(_OPENMP) #pragma omp parallel default(none) \ shared(f_start,f_stride,fc) \ reduction(+:oevdwl,oecoul,oedihedral,ov0,ov1,ov2,ov3,ov4,ov5, \ opv0,opv1,opv2,opv3,opv4,opv5) #endif { int nfrom, nto, tid; IP_PRE_omp_range_id(nfrom, nto, tid, inum, nthreads); FORCE_T * _noalias const f = f_start + (tid * f_stride); if (fix->need_zero(tid)) memset(f, 0, f_stride * sizeof(FORCE_T)); const int * _noalias const dihedrallist = (int *) neighbor->dihedrallist[0]; const flt_t * _noalias const weight = &(fc.weight[0]); const flt_t * _noalias const x_f = &(x[0].x); const flt_t * _noalias const cos_shift = &(fc.bp[0].cos_shift); const flt_t * _noalias const sin_shift = &(fc.bp[0].sin_shift); const flt_t * _noalias const k = &(fc.bp[0].k); const int * _noalias const multiplicity = &(fc.bp[0].multiplicity); const flt_t * _noalias const plj1 = &(fc.ljp[0][0].lj1); const flt_t * _noalias const plj2 = &(fc.ljp[0][0].lj2); const flt_t * _noalias const plj3 = &(fc.ljp[0][0].lj3); const flt_t * _noalias const plj4 = &(fc.ljp[0][0].lj4); acc_t * _noalias const pforce= &(f[0].x); acc_t * _noalias const featom = &(f[0].w); const flt_t qqrd2e = force->qqrd2e; SIMD_acc_t sedihedral, sv0, sv1, sv2, sv3, sv4, sv5; SIMD_acc_t sevdwl, secoul, spv0, spv1, spv2, spv3, spv4, spv5; if (EVFLAG) { if (EFLAG) { sevdwl = SIMD_set((acc_t)0.0); secoul = SIMD_set((acc_t)0.0); sedihedral = SIMD_set((acc_t)0.0); } if (vflag) { sv0 = SIMD_set((acc_t)0.0); sv1 = SIMD_set((acc_t)0.0); sv2 = SIMD_set((acc_t)0.0); sv3 = SIMD_set((acc_t)0.0); sv4 = SIMD_set((acc_t)0.0); sv5 = SIMD_set((acc_t)0.0); spv0 = SIMD_set((acc_t)0.0); spv1 = SIMD_set((acc_t)0.0); spv2 = SIMD_set((acc_t)0.0); spv3 = SIMD_set((acc_t)0.0); spv4 = SIMD_set((acc_t)0.0); spv5 = SIMD_set((acc_t)0.0); } } SIMD_int n_offset = SIMD_set(0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75) + (nfrom * 5); const int nto5 = nto * 5; const int nlocals4 = nlocal << 4; const SIMD_int simd_nlocals4 = SIMD_set(nlocals4); const int ntypes = atom->ntypes + 1; for (int n = nfrom; n < nto; n += swidth) { SIMD_mask nmask = n_offset < nto5; SIMD_int i1 = SIMD_gather(nmask, dihedrallist, n_offset); const SIMD_flt_t q1 = SIMD_gather(nmask, q, i1); i1 = i1 << 4; const SIMD_int i2 = SIMD_gather(nmask, dihedrallist+1, n_offset) << 4; const SIMD_int i3 = SIMD_gather(nmask, dihedrallist+2, n_offset) << 4; SIMD_int i4 = SIMD_gather(nmask, dihedrallist+3, n_offset); const SIMD_flt_t q4 = SIMD_gather(nmask, q, i4); i4 = i4 << 4; SIMD_int type = SIMD_gather(nmask, dihedrallist+4, n_offset); const SIMD_flt_t tweight = SIMD_gather(nmask, weight, type); type = type << 2; n_offset = n_offset + swidth * 5; // 1st bond SIMD_flt_t x1, x2, y1, y2, z1, z2; SIMD_int itype; SIMD_atom_gather(nmask, x_f, i1, x1, y1, z1, itype); SIMD_atom_gather(nmask, x_f, i2, x2, y2, z2); const SIMD_flt_t vb1x = x1 - x2; const SIMD_flt_t vb1y = y1 - y2; const SIMD_flt_t vb1z = z1 - z2; // 2nd bond SIMD_flt_t x3, y3, z3; SIMD_atom_gather(nmask, x_f, i3, x3, y3, z3); const SIMD_flt_t vb2xm = x2 - x3; const SIMD_flt_t vb2ym = y2 - y3; const SIMD_flt_t vb2zm = z2 - z3; // 3rd bond SIMD_flt_t x4, y4, z4; SIMD_int jtype; SIMD_atom_gather(nmask, x_f, i4, x4, y4, z4, jtype); const SIMD_flt_t vb3x = x4 - x3; const SIMD_flt_t vb3y = y4 - y3; const SIMD_flt_t vb3z = z4 - z3; // 1-4 const SIMD_flt_t delx = x1 - x4; const SIMD_flt_t dely = y1 - y4; const SIMD_flt_t delz = z1 - z4; // c,s calculation const SIMD_flt_t ax = vb1y*vb2zm - vb1z*vb2ym; const SIMD_flt_t ay = vb1z*vb2xm - vb1x*vb2zm; const SIMD_flt_t az = vb1x*vb2ym - vb1y*vb2xm; const SIMD_flt_t bx = vb3y*vb2zm - vb3z*vb2ym; const SIMD_flt_t by = vb3z*vb2xm - vb3x*vb2zm; const SIMD_flt_t bz = vb3x*vb2ym - vb3y*vb2xm; const SIMD_flt_t rasq = ax*ax + ay*ay + az*az; const SIMD_flt_t rbsq = bx*bx + by*by + bz*bz; const SIMD_flt_t rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm; const SIMD_flt_t rg = SIMD_sqrt(rgsq); const SIMD_flt_t szero = SIMD_set((flt_t)0.0); const SIMD_flt_t rginv = SIMD_rcpz(rg > szero, rg); const SIMD_flt_t ra2inv = SIMD_rcpz(rasq > szero, rasq); const SIMD_flt_t rb2inv = SIMD_rcpz(rbsq > szero, rbsq); const SIMD_flt_t rabinv = SIMD_sqrt(ra2inv*rb2inv); SIMD_flt_t c = (ax*bx + ay*by + az*bz)*rabinv; const SIMD_flt_t s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z); // error check const SIMD_flt_t one = SIMD_set((flt_t)1.0); const SIMD_flt_t mone = SIMD_set((flt_t)-1.0); const SIMD_flt_t ptol = SIMD_set(PTOLERANCE); const SIMD_flt_t ntol = SIMD_set(MTOLERANCE); if (c > ptol || c < ntol) if (screen) error->warning(FLERR,"Dihedral problem."); c = SIMD_set(c, c > one, one); c = SIMD_set(c, c < mone, mone); const SIMD_flt_t tcos_shift = SIMD_gather(nmask, cos_shift, type); const SIMD_flt_t tsin_shift = SIMD_gather(nmask, sin_shift, type); const SIMD_flt_t tk = SIMD_gather(nmask, k, type); const SIMD_int m = SIMD_gatherz_offset(nmask, multiplicity, type); SIMD_flt_t p(one); SIMD_flt_t ddf1(szero); SIMD_flt_t df1(szero); const int m_max = SIMD_max(m); for (int i = 0; i < m_max; i++) { const SIMD_mask my_m = i < m; ddf1 = SIMD_set(ddf1, my_m, p*c - df1*s); df1 = SIMD_set(df1, my_m, p*s + df1*c); p = SIMD_set(p, my_m, ddf1); } SIMD_flt_t multf; SIMD_cast(-m,multf); p = p*tcos_shift + df1*tsin_shift; df1 = df1*tcos_shift - ddf1*tsin_shift; df1 = df1 * multf; p = p + one; SIMD_mask mzero = (m == SIMD_set((int)0)); p = SIMD_set(p, mzero, one + tcos_shift); df1 = SIMD_set(df1, mzero, szero); const SIMD_flt_t fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm; const SIMD_flt_t hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm; const SIMD_flt_t fga = fg*ra2inv*rginv; const SIMD_flt_t hgb = hg*rb2inv*rginv; const SIMD_flt_t gaa = -ra2inv*rg; const SIMD_flt_t gbb = rb2inv*rg; const SIMD_flt_t dtfx = gaa*ax; const SIMD_flt_t dtfy = gaa*ay; const SIMD_flt_t dtfz = gaa*az; const SIMD_flt_t dtgx = fga*ax - hgb*bx; const SIMD_flt_t dtgy = fga*ay - hgb*by; const SIMD_flt_t dtgz = fga*az - hgb*bz; const SIMD_flt_t dthx = gbb*bx; const SIMD_flt_t dthy = gbb*by; const SIMD_flt_t dthz = gbb*bz; const SIMD_flt_t df = -tk * df1; const SIMD_flt_t sx2 = df*dtgx; const SIMD_flt_t sy2 = df*dtgy; const SIMD_flt_t sz2 = df*dtgz; SIMD_flt_t f1x = df*dtfx; SIMD_flt_t f1y = df*dtfy; SIMD_flt_t f1z = df*dtfz; SIMD_flt_t f2x = sx2 - f1x; SIMD_flt_t f2y = sy2 - f1y; SIMD_flt_t f2z = sz2 - f1z; SIMD_flt_t f4x = df*dthx; SIMD_flt_t f4y = df*dthy; SIMD_flt_t f4z = df*dthz; SIMD_flt_t f3x = -sx2 - f4x; SIMD_flt_t f3y = -sy2 - f4y; SIMD_flt_t f3z = -sz2 - f4z; SIMD_flt_t qdeng; if (EVFLAG) { SIMD_flt_t ev_pre; if (NEWTON_BOND) ev_pre = one; else { ev_pre = szero; const SIMD_flt_t quarter = SIMD_set((flt_t)0.25); ev_pre = SIMD_add(ev_pre, i1 < simd_nlocals4, ev_pre, quarter); ev_pre = SIMD_add(ev_pre, i2 < simd_nlocals4, ev_pre, quarter); ev_pre = SIMD_add(ev_pre, i3 < simd_nlocals4, ev_pre, quarter); ev_pre = SIMD_add(ev_pre, i4 < simd_nlocals4, ev_pre, quarter); } SIMD_zero_masked(nmask, ev_pre); if (EFLAG) { const SIMD_flt_t deng = tk * p; sedihedral = SIMD_ev_add(sedihedral, ev_pre * deng); if (eatom) { qdeng = deng * SIMD_set((flt_t)0.25); SIMD_mask newton_mask; if (NEWTON_BOND) newton_mask = nmask; if (!NEWTON_BOND) newton_mask = SIMD_lt(nmask, i2, simd_nlocals4); SIMD_flt_t ieng = qdeng; SIMD_jeng_update(newton_mask, featom, i2, ieng); ieng = qdeng; if (!NEWTON_BOND) newton_mask = SIMD_lt(nmask, i3, simd_nlocals4); SIMD_jeng_update(newton_mask, featom, i3, ieng); } } if (vflag) { sv0 = SIMD_ev_add(sv0, ev_pre*(vb1x*f1x-vb2xm*f3x+(vb3x-vb2xm)*f4x)); sv1 = SIMD_ev_add(sv1, ev_pre*(vb1y*f1y-vb2ym*f3y+(vb3y-vb2ym)*f4y)); sv2 = SIMD_ev_add(sv2, ev_pre*(vb1z*f1z-vb2zm*f3z+(vb3z-vb2zm)*f4z)); sv3 = SIMD_ev_add(sv3, ev_pre*(vb1x*f1y-vb2xm*f3y+(vb3x-vb2xm)*f4y)); sv4 = SIMD_ev_add(sv4, ev_pre*(vb1x*f1z-vb2xm*f3z+(vb3x-vb2xm)*f4z)); sv5 = SIMD_ev_add(sv5, ev_pre*(vb1y*f1z-vb2ym*f3z+(vb3y-vb2ym)*f4z)); } } SIMD_mask newton_mask; if (NEWTON_BOND) newton_mask = nmask; if (!NEWTON_BOND) newton_mask = SIMD_lt(nmask, i2, simd_nlocals4); SIMD_safe_jforce(newton_mask, pforce, i2, f2x, f2y, f2z); if (!NEWTON_BOND) newton_mask = SIMD_lt(nmask, i3, simd_nlocals4); SIMD_safe_jforce(newton_mask, pforce, i3, f3x, f3y, f3z); // 1-4 LJ and Coulomb interactions // tally energy/virial in pair, using newton_bond as newton flag const SIMD_flt_t rsq = delx*delx + dely*dely + delz*delz; const SIMD_flt_t r2inv = SIMD_rcpz(nmask, rsq); const SIMD_flt_t r6inv = r2inv*r2inv*r2inv; const SIMD_flt_t simd_qqrd2e = SIMD_set(qqrd2e); SIMD_flt_t forcecoul; if (implicit) forcecoul = simd_qqrd2e * q1 * q4 * r2inv; else forcecoul = simd_qqrd2e * q1 * q4 * SIMD_sqrt(r2inv); const SIMD_int ijtype = (itype * ntypes + jtype) << 2; const SIMD_flt_t lj1 = SIMD_gather(nmask, plj1, ijtype); const SIMD_flt_t lj2 = SIMD_gather(nmask, plj2, ijtype); const SIMD_flt_t forcelj = r6inv * (lj1 * r6inv - lj2); const SIMD_flt_t fpair = tweight * (forcelj + forcecoul) * r2inv; f1x = f1x + delx * fpair; f1y = f1y + dely * fpair; f1z = f1z + delz * fpair; f4x = f4x - delx * fpair; f4y = f4y - dely * fpair; f4z = f4z - delz * fpair; if (EVFLAG) { SIMD_flt_t ev_pre; if (NEWTON_BOND) ev_pre = one; else { ev_pre = szero; const SIMD_flt_t half = SIMD_set((flt_t)0.5); ev_pre = SIMD_add(ev_pre, i1 < simd_nlocals4,ev_pre,half); ev_pre = SIMD_add(ev_pre, i4 < simd_nlocals4,ev_pre,half); } SIMD_zero_masked(nmask, ev_pre); if (EFLAG) { const SIMD_flt_t ecoul = tweight * forcecoul; const SIMD_flt_t lj3 = SIMD_gather(nmask, plj3, ijtype); const SIMD_flt_t lj4 = SIMD_gather(nmask, plj4, ijtype); SIMD_flt_t evdwl = tweight * r6inv * (lj3 * r6inv - lj4); secoul = SIMD_ev_add(secoul, ev_pre * ecoul); sevdwl = SIMD_ev_add(sevdwl, ev_pre * evdwl); if (eatom) { const SIMD_flt_t half = SIMD_set((flt_t)0.5); evdwl = evdwl * half; evdwl = evdwl + half * ecoul + qdeng; if (NEWTON_BOND) newton_mask = nmask; if (!NEWTON_BOND) newton_mask = SIMD_lt(nmask, i1, simd_nlocals4); SIMD_flt_t ieng = evdwl; SIMD_jeng_update(newton_mask, featom, i1, ieng); ieng = evdwl; if (!NEWTON_BOND) newton_mask = SIMD_lt(nmask, i4, simd_nlocals4); SIMD_jeng_update(newton_mask, featom, i4, ieng); } } if (vflag) { spv0 = SIMD_ev_add(spv0, ev_pre * delx * delx * fpair); spv1 = SIMD_ev_add(spv1, ev_pre * dely * dely * fpair); spv2 = SIMD_ev_add(spv2, ev_pre * delz * delz * fpair); spv3 = SIMD_ev_add(spv3, ev_pre * delx * dely * fpair); spv4 = SIMD_ev_add(spv4, ev_pre * delx * delz * fpair); spv5 = SIMD_ev_add(spv5, ev_pre * dely * delz * fpair); } } if (NEWTON_BOND) newton_mask = nmask; if (!NEWTON_BOND) newton_mask = SIMD_lt(nmask, i1, simd_nlocals4); SIMD_safe_jforce(newton_mask, pforce, i1, f1x, f1y, f1z); if (!NEWTON_BOND) newton_mask = SIMD_lt(nmask, i4, simd_nlocals4); SIMD_safe_jforce(newton_mask, pforce, i4, f4x, f4y, f4z); } // for n if (EVFLAG) { if (EFLAG) { oedihedral += SIMD_sum(sedihedral); oecoul += SIMD_sum(secoul); oevdwl += SIMD_sum(sevdwl); } if (vflag) { ov0 += SIMD_sum(sv0); ov1 += SIMD_sum(sv1); ov2 += SIMD_sum(sv2); ov3 += SIMD_sum(sv3); ov4 += SIMD_sum(sv4); ov5 += SIMD_sum(sv5); opv0 += SIMD_sum(spv0); opv1 += SIMD_sum(spv1); opv2 += SIMD_sum(spv2); opv3 += SIMD_sum(spv3); opv4 += SIMD_sum(spv4); opv5 += SIMD_sum(spv5); } } } // omp parallel if (EVFLAG) { if (EFLAG) { energy += oedihedral; force->pair->eng_vdwl += oevdwl; force->pair->eng_coul += oecoul; } if (vflag) { virial[0] += ov0; virial[1] += ov1; virial[2] += ov2; virial[3] += ov3; virial[4] += ov4; virial[5] += ov5; force->pair->virial[0] += opv0; force->pair->virial[1] += opv1; force->pair->virial[2] += opv2; force->pair->virial[3] += opv3; force->pair->virial[4] += opv4; force->pair->virial[5] += opv5; } } fix->set_reduce_flag(); } #endif /* ---------------------------------------------------------------------- */ void DihedralCharmmIntel::init_style() { DihedralCharmm::init_style(); int ifix = modify->find_fix("package_intel"); if (ifix < 0) error->all(FLERR, "The 'package intel' command is required for /intel styles"); fix = static_cast(modify->fix[ifix]); #ifdef _LMP_INTEL_OFFLOAD _use_base = 0; if (fix->offload_balance() != 0.0) { _use_base = 1; return; } #endif fix->bond_init_check(); if (fix->precision() == FixIntel::PREC_MODE_MIXED) pack_force_const(force_const_single, fix->get_mixed_buffers()); else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) pack_force_const(force_const_double, fix->get_double_buffers()); else pack_force_const(force_const_single, fix->get_single_buffers()); } /* ---------------------------------------------------------------------- */ template void DihedralCharmmIntel::pack_force_const(ForceConst &fc, IntelBuffers *buffers) { const int tp1 = atom->ntypes + 1; const int bp1 = atom->ndihedraltypes + 1; fc.set_ntypes(tp1,bp1,memory); buffers->set_ntypes(tp1); for (int i = 0; i < tp1; i++) { for (int j = 0; j < tp1; j++) { fc.ljp[i][j].lj1 = lj14_1[i][j]; fc.ljp[i][j].lj2 = lj14_2[i][j]; fc.ljp[i][j].lj3 = lj14_3[i][j]; fc.ljp[i][j].lj4 = lj14_4[i][j]; } } for (int i = 0; i < bp1; i++) { fc.bp[i].multiplicity = multiplicity[i]; fc.bp[i].cos_shift = cos_shift[i]; fc.bp[i].sin_shift = sin_shift[i]; fc.bp[i].k = k[i]; fc.weight[i] = weight[i]; } } /* ---------------------------------------------------------------------- */ template void DihedralCharmmIntel::ForceConst::set_ntypes(const int npairtypes, const int nbondtypes, Memory *memory) { if (npairtypes != _npairtypes) { if (_npairtypes > 0) _memory->destroy(ljp); if (npairtypes > 0) memory->create(ljp,npairtypes,npairtypes,"fc.ljp"); } if (nbondtypes != _nbondtypes) { if (_nbondtypes > 0) { _memory->destroy(bp); _memory->destroy(weight); } if (nbondtypes > 0) { _memory->create(bp,nbondtypes,"dihedralcharmmintel.bp"); _memory->create(weight,nbondtypes,"dihedralcharmmintel.weight"); } } _npairtypes = npairtypes; _nbondtypes = nbondtypes; _memory = memory; } diff --git a/src/USER-INTEL/dihedral_harmonic_intel.cpp b/src/USER-INTEL/dihedral_harmonic_intel.cpp index aa6ba9d1d..03ab152f4 100644 --- a/src/USER-INTEL/dihedral_harmonic_intel.cpp +++ b/src/USER-INTEL/dihedral_harmonic_intel.cpp @@ -1,411 +1,411 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: W. Michael Brown (Intel) ------------------------------------------------------------------------- */ -#include "mpi.h" -#include "math.h" +#include +#include #include "dihedral_harmonic_intel.h" #include "atom.h" #include "comm.h" #include "memory.h" #include "neighbor.h" #include "domain.h" #include "force.h" #include "pair.h" #include "update.h" #include "error.h" #include "suffix.h" using namespace LAMMPS_NS; #define PTOLERANCE (flt_t)1.05 #define MTOLERANCE (flt_t)-1.05 typedef struct { int a,b,c,d,t; } int5_t; /* ---------------------------------------------------------------------- */ DihedralHarmonicIntel::DihedralHarmonicIntel(class LAMMPS *lmp) : DihedralHarmonic(lmp) { suffix_flag |= Suffix::INTEL; } /* ---------------------------------------------------------------------- */ void DihedralHarmonicIntel::compute(int eflag, int vflag) { #ifdef _LMP_INTEL_OFFLOAD if (_use_base) { DihedralHarmonic::compute(eflag, vflag); return; } #endif if (fix->precision() == FixIntel::PREC_MODE_MIXED) compute(eflag, vflag, fix->get_mixed_buffers(), force_const_single); else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) compute(eflag, vflag, fix->get_double_buffers(), force_const_double); else compute(eflag, vflag, fix->get_single_buffers(), force_const_single); } /* ---------------------------------------------------------------------- */ template void DihedralHarmonicIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { if (eflag || vflag) { ev_setup(eflag,vflag); } else evflag = 0; if (evflag) { if (eflag) { if (force->newton_bond) eval<1,1,1>(vflag, buffers, fc); else eval<1,1,0>(vflag, buffers, fc); } else { if (force->newton_bond) eval<1,0,1>(vflag, buffers, fc); else eval<1,0,0>(vflag, buffers, fc); } } else { if (force->newton_bond) eval<0,0,1>(vflag, buffers, fc); else eval<0,0,0>(vflag, buffers, fc); } } template void DihedralHarmonicIntel::eval(const int vflag, IntelBuffers *buffers, const ForceConst &fc) { const int inum = neighbor->ndihedrallist; if (inum == 0) return; ATOM_T * _noalias const x = buffers->get_x(0); const int nlocal = atom->nlocal; const int nall = nlocal + atom->nghost; int f_stride; if (NEWTON_BOND) f_stride = buffers->get_stride(nall); else f_stride = buffers->get_stride(nlocal); int tc; FORCE_T * _noalias f_start; acc_t * _noalias ev_global; IP_PRE_get_buffers(0, buffers, fix, tc, f_start, ev_global); const int nthreads = tc; acc_t oedihedral, ov0, ov1, ov2, ov3, ov4, ov5; if (EVFLAG) { if (EFLAG) oedihedral = (acc_t)0.0; if (vflag) { ov0 = ov1 = ov2 = ov3 = ov4 = ov5 = (acc_t)0.0; } } #if defined(_OPENMP) #pragma omp parallel default(none) \ shared(f_start,f_stride,fc) \ reduction(+:oedihedral,ov0,ov1,ov2,ov3,ov4,ov5) #endif { int nfrom, nto, tid; IP_PRE_omp_range_id(nfrom, nto, tid, inum, nthreads); FORCE_T * _noalias const f = f_start + (tid * f_stride); if (fix->need_zero(tid)) memset(f, 0, f_stride * sizeof(FORCE_T)); const int5_t * _noalias const dihedrallist = (int5_t *) neighbor->dihedrallist[0]; acc_t sedihedral, sv0, sv1, sv2, sv3, sv4, sv5; if (EVFLAG) { if (EFLAG) sedihedral = (acc_t)0.0; if (vflag) { sv0 = sv1 = sv2 = sv3 = sv4 = sv5 = (acc_t)0.0; } } for (int n = nfrom; n < nto; n++) { const int i1 = dihedrallist[n].a; const int i2 = dihedrallist[n].b; const int i3 = dihedrallist[n].c; const int i4 = dihedrallist[n].d; const int type = dihedrallist[n].t; // 1st bond const flt_t vb1x = x[i1].x - x[i2].x; const flt_t vb1y = x[i1].y - x[i2].y; const flt_t vb1z = x[i1].z - x[i2].z; // 2nd bond const flt_t vb2xm = x[i2].x - x[i3].x; const flt_t vb2ym = x[i2].y - x[i3].y; const flt_t vb2zm = x[i2].z - x[i3].z; // 3rd bond const flt_t vb3x = x[i4].x - x[i3].x; const flt_t vb3y = x[i4].y - x[i3].y; const flt_t vb3z = x[i4].z - x[i3].z; // c,s calculation const flt_t ax = vb1y*vb2zm - vb1z*vb2ym; const flt_t ay = vb1z*vb2xm - vb1x*vb2zm; const flt_t az = vb1x*vb2ym - vb1y*vb2xm; const flt_t bx = vb3y*vb2zm - vb3z*vb2ym; const flt_t by = vb3z*vb2xm - vb3x*vb2zm; const flt_t bz = vb3x*vb2ym - vb3y*vb2xm; const flt_t rasq = ax*ax + ay*ay + az*az; const flt_t rbsq = bx*bx + by*by + bz*bz; const flt_t rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm; const flt_t rg = sqrt(rgsq); flt_t rginv, ra2inv, rb2inv; rginv = ra2inv = rb2inv = (flt_t)0.0; if (rg > 0) rginv = (flt_t)1.0/rg; if (rasq > 0) ra2inv = (flt_t)1.0/rasq; if (rbsq > 0) rb2inv = (flt_t)1.0/rbsq; const flt_t rabinv = sqrt(ra2inv*rb2inv); flt_t c = (ax*bx + ay*by + az*bz)*rabinv; const flt_t s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z); // error check if (c > PTOLERANCE || c < MTOLERANCE) { int me = comm->me; if (screen) { char str[128]; sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, me,tid,update->ntimestep, atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); error->warning(FLERR,str,0); fprintf(screen," 1st atom: %d %g %g %g\n", me,x[i1].x,x[i1].y,x[i1].z); fprintf(screen," 2nd atom: %d %g %g %g\n", me,x[i2].x,x[i2].y,x[i2].z); fprintf(screen," 3rd atom: %d %g %g %g\n", me,x[i3].x,x[i3].y,x[i3].z); fprintf(screen," 4th atom: %d %g %g %g\n", me,x[i4].x,x[i4].y,x[i4].z); } } if (c > (flt_t)1.0) c = (flt_t)1.0; if (c < (flt_t)-1.0) c = (flt_t)-1.0; const flt_t tcos_shift = fc.bp[type].cos_shift; const flt_t tsin_shift = fc.bp[type].sin_shift; const flt_t tk = fc.bp[type].k; const int m = fc.bp[type].multiplicity; flt_t p = (flt_t)1.0; flt_t ddf1, df1; ddf1 = df1 = (flt_t)0.0; for (int i = 0; i < m; i++) { ddf1 = p*c - df1*s; df1 = p*s + df1*c; p = ddf1; } p = p*tcos_shift + df1*tsin_shift; df1 = df1*tcos_shift - ddf1*tsin_shift; df1 *= -m; p += (flt_t)1.0; if (m == 0) { p = (flt_t)1.0 + tcos_shift; df1 = (flt_t)0.0; } const flt_t fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm; const flt_t hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm; const flt_t fga = fg*ra2inv*rginv; const flt_t hgb = hg*rb2inv*rginv; const flt_t gaa = -ra2inv*rg; const flt_t gbb = rb2inv*rg; const flt_t dtfx = gaa*ax; const flt_t dtfy = gaa*ay; const flt_t dtfz = gaa*az; const flt_t dtgx = fga*ax - hgb*bx; const flt_t dtgy = fga*ay - hgb*by; const flt_t dtgz = fga*az - hgb*bz; const flt_t dthx = gbb*bx; const flt_t dthy = gbb*by; const flt_t dthz = gbb*bz; const flt_t df = -tk * df1; const flt_t sx2 = df*dtgx; const flt_t sy2 = df*dtgy; const flt_t sz2 = df*dtgz; flt_t f1x = df*dtfx; flt_t f1y = df*dtfy; flt_t f1z = df*dtfz; const flt_t f2x = sx2 - f1x; const flt_t f2y = sy2 - f1y; const flt_t f2z = sz2 - f1z; flt_t f4x = df*dthx; flt_t f4y = df*dthy; flt_t f4z = df*dthz; const flt_t f3x = -sx2 - f4x; const flt_t f3y = -sy2 - f4y; const flt_t f3z = -sz2 - f4z; if (EVFLAG) { flt_t deng; if (EFLAG) deng = tk * p; IP_PRE_ev_tally_dihed(EFLAG, eatom, vflag, deng, i1, i2, i3, i4, f1x, f1y, f1z, f3x, f3y, f3z, f4x, f4y, f4z, vb1x, vb1y, vb1z, -vb2xm, -vb2ym, -vb2zm, vb3x, vb3y, vb3z, sedihedral, f, NEWTON_BOND, nlocal, sv0, sv1, sv2, sv3, sv4, sv5); } { if (NEWTON_BOND || i1 < nlocal) { f[i1].x += f1x; f[i1].y += f1y; f[i1].z += f1z; } if (NEWTON_BOND || i2 < nlocal) { f[i2].x += f2x; f[i2].y += f2y; f[i2].z += f2z; } if (NEWTON_BOND || i3 < nlocal) { f[i3].x += f3x; f[i3].y += f3y; f[i3].z += f3z; } if (NEWTON_BOND || i4 < nlocal) { f[i4].x += f4x; f[i4].y += f4y; f[i4].z += f4z; } } } // for n if (EVFLAG) { if (EFLAG) oedihedral += sedihedral; if (vflag) { ov0 += sv0; ov1 += sv1; ov2 += sv2; ov3 += sv3; ov4 += sv4; ov5 += sv5; } } } // omp parallel if (EVFLAG) { if (EFLAG) energy += oedihedral; if (vflag) { virial[0] += ov0; virial[1] += ov1; virial[2] += ov2; virial[3] += ov3; virial[4] += ov4; virial[5] += ov5; } } fix->set_reduce_flag(); } /* ---------------------------------------------------------------------- */ void DihedralHarmonicIntel::init_style() { DihedralHarmonic::init_style(); int ifix = modify->find_fix("package_intel"); if (ifix < 0) error->all(FLERR, "The 'package intel' command is required for /intel styles"); fix = static_cast(modify->fix[ifix]); #ifdef _LMP_INTEL_OFFLOAD _use_base = 0; if (fix->offload_balance() != 0.0) { _use_base = 1; return; } #endif fix->bond_init_check(); if (fix->precision() == FixIntel::PREC_MODE_MIXED) pack_force_const(force_const_single, fix->get_mixed_buffers()); else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) pack_force_const(force_const_double, fix->get_double_buffers()); else pack_force_const(force_const_single, fix->get_single_buffers()); } /* ---------------------------------------------------------------------- */ template void DihedralHarmonicIntel::pack_force_const(ForceConst &fc, IntelBuffers *buffers) { const int bp1 = atom->ndihedraltypes + 1; fc.set_ntypes(bp1,memory); for (int i = 0; i < bp1; i++) { fc.bp[i].multiplicity = multiplicity[i]; fc.bp[i].cos_shift = cos_shift[i]; fc.bp[i].sin_shift = sin_shift[i]; fc.bp[i].k = k[i]; } } /* ---------------------------------------------------------------------- */ template void DihedralHarmonicIntel::ForceConst::set_ntypes(const int nbondtypes, Memory *memory) { if (nbondtypes != _nbondtypes) { if (_nbondtypes > 0) _memory->destroy(bp); if (nbondtypes > 0) _memory->create(bp,nbondtypes,"dihedralcharmmintel.bp"); } _nbondtypes = nbondtypes; _memory = memory; } diff --git a/src/USER-INTEL/dihedral_opls_intel.cpp b/src/USER-INTEL/dihedral_opls_intel.cpp index 1edb52f05..bfd5a5395 100644 --- a/src/USER-INTEL/dihedral_opls_intel.cpp +++ b/src/USER-INTEL/dihedral_opls_intel.cpp @@ -1,438 +1,438 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: W. Michael Brown (Intel) ------------------------------------------------------------------------- */ -#include "mpi.h" -#include "math.h" +#include +#include #include "dihedral_opls_intel.h" #include "atom.h" #include "comm.h" #include "memory.h" #include "neighbor.h" #include "domain.h" #include "force.h" #include "pair.h" #include "update.h" #include "error.h" #include "suffix.h" using namespace LAMMPS_NS; #define PTOLERANCE (flt_t)1.05 #define MTOLERANCE (flt_t)-1.05 #define SMALL2 (flt_t)0.000001 #define INVSMALL (flt_t)1000.0 #define SMALLER2 (flt_t)0.0000000001 #define INVSMALLER (flt_t)100000.0 typedef struct { int a,b,c,d,t; } int5_t; /* ---------------------------------------------------------------------- */ DihedralOPLSIntel::DihedralOPLSIntel(class LAMMPS *lmp) : DihedralOPLS(lmp) { suffix_flag |= Suffix::INTEL; } /* ---------------------------------------------------------------------- */ void DihedralOPLSIntel::compute(int eflag, int vflag) { #ifdef _LMP_INTEL_OFFLOAD if (_use_base) { DihedralOPLS::compute(eflag, vflag); return; } #endif if (fix->precision() == FixIntel::PREC_MODE_MIXED) compute(eflag, vflag, fix->get_mixed_buffers(), force_const_single); else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) compute(eflag, vflag, fix->get_double_buffers(), force_const_double); else compute(eflag, vflag, fix->get_single_buffers(), force_const_single); } /* ---------------------------------------------------------------------- */ template void DihedralOPLSIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { if (eflag || vflag) { ev_setup(eflag,vflag); } else evflag = 0; if (evflag) { if (eflag) { if (force->newton_bond) eval<1,1,1>(vflag, buffers, fc); else eval<1,1,0>(vflag, buffers, fc); } else { if (force->newton_bond) eval<1,0,1>(vflag, buffers, fc); else eval<1,0,0>(vflag, buffers, fc); } } else { if (force->newton_bond) eval<0,0,1>(vflag, buffers, fc); else eval<0,0,0>(vflag, buffers, fc); } } template void DihedralOPLSIntel::eval(const int vflag, IntelBuffers *buffers, const ForceConst &fc) { const int inum = neighbor->ndihedrallist; if (inum == 0) return; ATOM_T * _noalias const x = buffers->get_x(0); const int nlocal = atom->nlocal; const int nall = nlocal + atom->nghost; int f_stride; if (NEWTON_BOND) f_stride = buffers->get_stride(nall); else f_stride = buffers->get_stride(nlocal); int tc; FORCE_T * _noalias f_start; acc_t * _noalias ev_global; IP_PRE_get_buffers(0, buffers, fix, tc, f_start, ev_global); const int nthreads = tc; acc_t oedihedral, ov0, ov1, ov2, ov3, ov4, ov5; if (EVFLAG) { if (EFLAG) oedihedral = (acc_t)0.0; if (vflag) { ov0 = ov1 = ov2 = ov3 = ov4 = ov5 = (acc_t)0.0; } } #if defined(_OPENMP) #pragma omp parallel default(none) \ shared(f_start,f_stride,fc) \ reduction(+:oedihedral,ov0,ov1,ov2,ov3,ov4,ov5) #endif { int nfrom, nto, tid; IP_PRE_omp_range_id(nfrom, nto, tid, inum, nthreads); FORCE_T * _noalias const f = f_start + (tid * f_stride); if (fix->need_zero(tid)) memset(f, 0, f_stride * sizeof(FORCE_T)); const int5_t * _noalias const dihedrallist = (int5_t *) neighbor->dihedrallist[0]; acc_t sedihedral, sv0, sv1, sv2, sv3, sv4, sv5; if (EVFLAG) { if (EFLAG) sedihedral = (acc_t)0.0; if (vflag) { sv0 = sv1 = sv2 = sv3 = sv4 = sv5 = (acc_t)0.0; } } for (int n = nfrom; n < nto; n++) { const int i1 = dihedrallist[n].a; const int i2 = dihedrallist[n].b; const int i3 = dihedrallist[n].c; const int i4 = dihedrallist[n].d; const int type = dihedrallist[n].t; // 1st bond const flt_t vb1x = x[i1].x - x[i2].x; const flt_t vb1y = x[i1].y - x[i2].y; const flt_t vb1z = x[i1].z - x[i2].z; // 2nd bond const flt_t vb2xm = x[i2].x - x[i3].x; const flt_t vb2ym = x[i2].y - x[i3].y; const flt_t vb2zm = x[i2].z - x[i3].z; // 3rd bond const flt_t vb3x = x[i4].x - x[i3].x; const flt_t vb3y = x[i4].y - x[i3].y; const flt_t vb3z = x[i4].z - x[i3].z; // 1-4 const flt_t delx = x[i1].x - x[i4].x; const flt_t dely = x[i1].y - x[i4].y; const flt_t delz = x[i1].z - x[i4].z; // c0 calculation // 1st and 2nd angle const flt_t b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z; const flt_t rb1 = (flt_t)1.0 / sqrt(b1mag2); const flt_t sb1 = (flt_t)1.0 / b1mag2; const flt_t b2mag2 = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm; const flt_t rb2 = (flt_t)1.0 / sqrt(b2mag2); const flt_t sb2 = (flt_t)1.0 / b2mag2; const flt_t b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z; const flt_t rb3 = (flt_t)1.0 / sqrt(b3mag2); const flt_t sb3 = (flt_t)1.0 / b3mag2; const flt_t c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3; flt_t ctmp = -vb1x*vb2xm - vb1y*vb2ym - vb1z*vb2zm; const flt_t r12c1 = rb1 * rb2; const flt_t c1mag = ctmp * r12c1; ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z; const flt_t r12c2 = rb2 * rb3; const flt_t c2mag = ctmp * r12c2; // cos and sin of 2 angles and final c flt_t sin2 = MAX((flt_t)1.0 - c1mag*c1mag,(flt_t)0.0); flt_t sc1 = (flt_t)1.0/sqrt(sin2); if (sin2 < SMALL2) sc1 = INVSMALL; sin2 = MAX((flt_t)1.0 - c2mag*c2mag,(flt_t)0.0); flt_t sc2 = (flt_t)1.0/sqrt(sin2); if (sin2 < SMALL2) sc2 = INVSMALL; const flt_t s1 = sc1 * sc1; const flt_t s2 = sc2 * sc2; flt_t s12 = sc1 * sc2; flt_t c = (c0 + c1mag*c2mag) * s12; const flt_t cx = vb1z*vb2ym - vb1y*vb2zm; const flt_t cy = vb1x*vb2zm - vb1z*vb2xm; const flt_t cz = vb1y*vb2xm - vb1x*vb2ym; const flt_t cmag = (flt_t)1.0/sqrt(cx*cx + cy*cy + cz*cz); const flt_t dx = (cx*vb3x + cy*vb3y + cz*vb3z)*cmag*rb3; // error check if (c > PTOLERANCE || c < MTOLERANCE) { int me = comm->me; if (screen) { char str[128]; sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, me,tid,update->ntimestep, atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); error->warning(FLERR,str,0); fprintf(screen," 1st atom: %d %g %g %g\n", me,x[i1].x,x[i1].y,x[i1].z); fprintf(screen," 2nd atom: %d %g %g %g\n", me,x[i2].x,x[i2].y,x[i2].z); fprintf(screen," 3rd atom: %d %g %g %g\n", me,x[i3].x,x[i3].y,x[i3].z); fprintf(screen," 4th atom: %d %g %g %g\n", me,x[i4].x,x[i4].y,x[i4].z); } } if (c > (flt_t)1.0) c = (flt_t)1.0; if (c < (flt_t)-1.0) c = (flt_t)-1.0; // force & energy // p = sum (i=1,4) k_i * (1 + (-1)**(i+1)*cos(i*phi) ) // pd = dp/dc const flt_t cossq = c * c; const flt_t sinsq = (flt_t)1.0 - cossq; flt_t siinv = (flt_t)1.0/sqrt(sinsq); if (sinsq < SMALLER2 ) siinv = INVSMALLER; if (dx < (flt_t)0.0) siinv = -siinv; const flt_t cos_2phi = cossq - sinsq; const flt_t sin_2phim = (flt_t)2.0 * c; const flt_t cos_3phi = (flt_t)2.0 * c * cos_2phi - c; const flt_t sin_3phim = (flt_t)2.0 * cos_2phi + (flt_t)1.0; const flt_t cos_4phi = (flt_t)2.0 * cos_2phi * cos_2phi - (flt_t)1.0; const flt_t sin_4phim = (flt_t)2.0 * cos_2phi * sin_2phim; flt_t p, pd; p = fc.bp[type].k1*((flt_t)1.0 + c) + fc.bp[type].k2*((flt_t)1.0 - cos_2phi) + fc.bp[type].k3*((flt_t)1.0 + cos_3phi) + fc.bp[type].k4*((flt_t)1.0 - cos_4phi) ; pd = fc.bp[type].k1 - (flt_t)2.0 * fc.bp[type].k2 * sin_2phim + (flt_t)3.0 * fc.bp[type].k3 * sin_3phim - (flt_t)4.0 * fc.bp[type].k4 * sin_4phim; flt_t edihed; if (EFLAG) edihed = p; const flt_t a = pd; c = c * a; s12 = s12 * a; const flt_t a11 = c*sb1*s1; const flt_t a22 = -sb2 * ((flt_t)2.0*c0*s12 - c*(s1+s2)); const flt_t a33 = c*sb3*s2; const flt_t a12 = -r12c1 * (c1mag*c*s1 + c2mag*s12); const flt_t a13 = -rb1*rb3*s12; const flt_t a23 = r12c2 * (c2mag*c*s2 + c1mag*s12); const flt_t sx2 = a12*vb1x - a22*vb2xm + a23*vb3x; const flt_t sy2 = a12*vb1y - a22*vb2ym + a23*vb3y; const flt_t sz2 = a12*vb1z - a22*vb2zm + a23*vb3z; const flt_t f1x = a11*vb1x - a12*vb2xm + a13*vb3x; const flt_t f1y = a11*vb1y - a12*vb2ym + a13*vb3y; const flt_t f1z = a11*vb1z - a12*vb2zm + a13*vb3z; const flt_t f2x = -sx2 - f1x; const flt_t f2y = -sy2 - f1y; const flt_t f2z = -sz2 - f1z; const flt_t f4x = a13*vb1x - a23*vb2xm + a33*vb3x; const flt_t f4y = a13*vb1y - a23*vb2ym + a33*vb3y; const flt_t f4z = a13*vb1z - a23*vb2zm + a33*vb3z; const flt_t f3x = sx2 - f4x; const flt_t f3y = sy2 - f4y; const flt_t f3z = sz2 - f4z; if (EVFLAG) { IP_PRE_ev_tally_dihed(EFLAG, eatom, vflag, edihed, i1, i2, i3, i4, f1x, f1y, f1z, f3x, f3y, f3z, f4x, f4y, f4z, vb1x, vb1y, vb1z, -vb2xm, -vb2ym, -vb2zm, vb3x, vb3y, vb3z, sedihedral, f, NEWTON_BOND, nlocal, sv0, sv1, sv2, sv3, sv4, sv5); } { if (NEWTON_BOND || i1 < nlocal) { f[i1].x += f1x; f[i1].y += f1y; f[i1].z += f1z; } if (NEWTON_BOND || i2 < nlocal) { f[i2].x += f2x; f[i2].y += f2y; f[i2].z += f2z; } if (NEWTON_BOND || i3 < nlocal) { f[i3].x += f3x; f[i3].y += f3y; f[i3].z += f3z; } if (NEWTON_BOND || i4 < nlocal) { f[i4].x += f4x; f[i4].y += f4y; f[i4].z += f4z; } } } // for n if (EVFLAG) { if (EFLAG) oedihedral += sedihedral; if (vflag) { ov0 += sv0; ov1 += sv1; ov2 += sv2; ov3 += sv3; ov4 += sv4; ov5 += sv5; } } } // omp parallel if (EVFLAG) { if (EFLAG) energy += oedihedral; if (vflag) { virial[0] += ov0; virial[1] += ov1; virial[2] += ov2; virial[3] += ov3; virial[4] += ov4; virial[5] += ov5; } } fix->set_reduce_flag(); } /* ---------------------------------------------------------------------- */ void DihedralOPLSIntel::init_style() { DihedralOPLS::init_style(); int ifix = modify->find_fix("package_intel"); if (ifix < 0) error->all(FLERR, "The 'package intel' command is required for /intel styles"); fix = static_cast(modify->fix[ifix]); #ifdef _LMP_INTEL_OFFLOAD _use_base = 0; if (fix->offload_balance() != 0.0) { _use_base = 1; return; } #endif fix->bond_init_check(); if (fix->precision() == FixIntel::PREC_MODE_MIXED) pack_force_const(force_const_single, fix->get_mixed_buffers()); else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) pack_force_const(force_const_double, fix->get_double_buffers()); else pack_force_const(force_const_single, fix->get_single_buffers()); } /* ---------------------------------------------------------------------- */ template void DihedralOPLSIntel::pack_force_const(ForceConst &fc, IntelBuffers *buffers) { const int bp1 = atom->ndihedraltypes + 1; fc.set_ntypes(bp1,memory); for (int i = 0; i < bp1; i++) { fc.bp[i].k1 = k1[i]; fc.bp[i].k2 = k2[i]; fc.bp[i].k3 = k3[i]; fc.bp[i].k4 = k4[i]; } } /* ---------------------------------------------------------------------- */ template void DihedralOPLSIntel::ForceConst::set_ntypes(const int nbondtypes, Memory *memory) { if (nbondtypes != _nbondtypes) { if (_nbondtypes > 0) _memory->destroy(bp); if (nbondtypes > 0) _memory->create(bp,nbondtypes,"dihedralcharmmintel.bp"); } _nbondtypes = nbondtypes; _memory = memory; } diff --git a/src/USER-INTEL/fix_npt_intel.cpp b/src/USER-INTEL/fix_npt_intel.cpp index 2bfbd5e73..56df3bba4 100644 --- a/src/USER-INTEL/fix_npt_intel.cpp +++ b/src/USER-INTEL/fix_npt_intel.cpp @@ -1,68 +1,68 @@ /* ---------------------------------------------------------------------- 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 "string.h" +#include #include "fix_npt_intel.h" #include "modify.h" #include "error.h" using namespace LAMMPS_NS; using namespace FixConst; /* ---------------------------------------------------------------------- */ FixNPTIntel::FixNPTIntel(LAMMPS *lmp, int narg, char **arg) : FixNHIntel(lmp, narg, arg) { if (!tstat_flag) error->all(FLERR,"Temperature control must be used with fix npt/omp"); if (!pstat_flag) error->all(FLERR,"Pressure control must be used with fix npt/omp"); // create a new compute temp style // id = fix-ID + temp // compute group = all since pressure is always global (group all) // and thus its KE/temperature contribution should use group all int n = strlen(id) + 6; id_temp = new char[n]; strcpy(id_temp,id); strcat(id_temp,"_temp"); char **newarg = new char*[3]; newarg[0] = id_temp; newarg[1] = (char *) "all"; newarg[2] = (char *) "temp"; modify->add_compute(3,newarg); delete [] newarg; tcomputeflag = 1; // create a new compute pressure style // id = fix-ID + press, compute group = all // pass id_temp as 4th arg to pressure constructor n = strlen(id) + 7; id_press = new char[n]; strcpy(id_press,id); strcat(id_press,"_press"); newarg = new char*[4]; newarg[0] = id_press; newarg[1] = (char *) "all"; newarg[2] = (char *) "pressure"; newarg[3] = id_temp; modify->add_compute(4,newarg); delete [] newarg; pcomputeflag = 1; } diff --git a/src/USER-INTEL/fix_nve_asphere_intel.cpp b/src/USER-INTEL/fix_nve_asphere_intel.cpp index f43519663..656316545 100644 --- a/src/USER-INTEL/fix_nve_asphere_intel.cpp +++ b/src/USER-INTEL/fix_nve_asphere_intel.cpp @@ -1,238 +1,238 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: W. Michael Brown (Intel) ------------------------------------------------------------------------- */ -#include "math.h" -#include "stdio.h" -#include "string.h" +#include +#include +#include #include "fix_nve_asphere_intel.h" #include "math_extra_intel.h" #include "atom.h" #include "atom_vec_ellipsoid.h" #include "force.h" #include "neighbor.h" #include "update.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; using namespace FixConst; #define INERTIA 0.2 // moment of inertia prefactor for ellipsoid /* ---------------------------------------------------------------------- */ FixNVEAsphereIntel::FixNVEAsphereIntel(LAMMPS *lmp, int narg, char **arg) : FixNVE(lmp, narg, arg) { _dtfm = 0; _nlocal3 = 0; _nlocal_max = 0; _inertia0 = 0; _inertia1 = 0; _inertia2 = 0; } /* ---------------------------------------------------------------------- */ void FixNVEAsphereIntel::init() { avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); if (!avec) error->all(FLERR,"Compute nve/asphere requires atom style ellipsoid"); // check that all particles are finite-size ellipsoids // no point particles allowed, spherical is OK int *ellipsoid = atom->ellipsoid; int *mask = atom->mask; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) if (ellipsoid[i] < 0) error->one(FLERR,"Fix nve/asphere requires extended particles"); FixNVE::init(); } /* ---------------------------------------------------------------------- */ void FixNVEAsphereIntel::setup(int vflag) { FixNVE::setup(vflag); reset_dt(); } /* ---------------------------------------------------------------------- */ void FixNVEAsphereIntel::initial_integrate(int vflag) { double dtfm; double inertia[3],omega[3]; double *shape,*quat; AtomVecEllipsoid::Bonus *bonus = avec->bonus; int *ellipsoid = atom->ellipsoid; double * _noalias const x = atom->x[0]; double * _noalias const v = atom->v[0]; const double * _noalias const f = atom->f[0]; int *mask = atom->mask; double **angmom = atom->angmom; double **torque = atom->torque; double *rmass = atom->rmass; int nlocal = atom->nlocal; if (igroup == atom->firstgroup) nlocal = atom->nfirst; // set timestep here since dt may have changed or come via rRESPA dtq = 0.5 * dtv; #if defined(LMP_SIMD_COMPILER) #pragma vector aligned #pragma simd #endif for (int i = 0; i < _nlocal3; i++) { v[i] += _dtfm[i] * f[i]; x[i] += dtv * v[i]; } // update angular momentum by 1/2 step if (igroup == 0) { #if defined(LMP_SIMD_COMPILER) #pragma vector aligned #pragma simd #endif for (int i = 0; i < nlocal; i++) { double *quat = bonus[ellipsoid[i]].quat; ME_omega_richardson(dtf, dtq, angmom[i], quat, torque[i], _inertia0[i], _inertia1[i], _inertia2[i]); } } else { #if defined(LMP_SIMD_COMPILER) #pragma vector aligned #pragma simd #endif for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { double *quat = bonus[ellipsoid[i]].quat; ME_omega_richardson(dtf, dtq, angmom[i], quat, torque[i], _inertia0[i], _inertia1[i], _inertia2[i]); } } } } /* ---------------------------------------------------------------------- */ void FixNVEAsphereIntel::final_integrate() { if (neighbor->ago == 0) reset_dt(); double dtfm; double * _noalias const v = atom->v[0]; const double * _noalias const f = atom->f[0]; double * _noalias const angmom = atom->angmom[0]; const double * _noalias const torque = atom->torque[0]; #if defined(LMP_SIMD_COMPILER) #pragma vector aligned #pragma simd #endif for (int i = 0; i < _nlocal3; i++) { v[i] += _dtfm[i] * f[i]; angmom[i] += dtf * torque[i]; } } void FixNVEAsphereIntel::reset_dt() { AtomVecEllipsoid::Bonus *bonus = avec->bonus; int *ellipsoid = atom->ellipsoid; dtv = update->dt; dtf = 0.5 * update->dt * force->ftm2v; const int * const mask = atom->mask; const int nlocal = (igroup == atom->firstgroup) ? atom->nfirst : atom->nlocal; if (nlocal > _nlocal_max) { if (_nlocal_max) { memory->destroy(_dtfm); memory->destroy(_inertia0); memory->destroy(_inertia1); memory->destroy(_inertia2); } _nlocal_max = static_cast(1.20 * nlocal); memory->create(_dtfm, _nlocal_max * 3, "fix_nve_intel:dtfm"); memory->create(_inertia0, _nlocal_max * 3, "fix_nve_intel:inertia0"); memory->create(_inertia1, _nlocal_max * 3, "fix_nve_intel:inertia1"); memory->create(_inertia2, _nlocal_max * 3, "fix_nve_intel:inertia2"); } _nlocal3 = nlocal * 3; if (igroup == 0) { const double * const rmass = atom->rmass; int n = 0; for (int i = 0; i < nlocal; i++) { _dtfm[n++] = dtf / rmass[i]; _dtfm[n++] = dtf / rmass[i]; _dtfm[n++] = dtf / rmass[i]; double *shape = bonus[ellipsoid[i]].shape; double idot = INERTIA*rmass[i] * (shape[1]*shape[1]+shape[2]*shape[2]); if (idot != 0.0) idot = 1.0 / idot; _inertia0[i] = idot; idot = INERTIA*rmass[i] * (shape[0]*shape[0]+shape[2]*shape[2]); if (idot != 0.0) idot = 1.0 / idot; _inertia1[i] = idot; idot = INERTIA*rmass[i] * (shape[0]*shape[0]+shape[1]*shape[1]); if (idot != 0.0) idot = 1.0 / idot; _inertia2[i] = idot; } } else { const double * const rmass = atom->rmass; int n = 0; for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { _dtfm[n++] = dtf / rmass[i]; _dtfm[n++] = dtf / rmass[i]; _dtfm[n++] = dtf / rmass[i]; double *shape = bonus[ellipsoid[i]].shape; double idot = INERTIA*rmass[i] * (shape[1]*shape[1]+shape[2]*shape[2]); if (idot != 0.0) idot = 1.0 / idot; _inertia0[i] = idot; idot = INERTIA*rmass[i] * (shape[0]*shape[0]+shape[2]*shape[2]); if (idot != 0.0) idot = 1.0 / idot; _inertia1[i] = idot; idot = INERTIA*rmass[i] * (shape[0]*shape[0]+shape[1]*shape[1]); if (idot != 0.0) idot = 1.0 / idot; _inertia2[i] = idot; } else { _dtfm[n++] = 0.0; _dtfm[n++] = 0.0; _dtfm[n++] = 0.0; } } } } double FixNVEAsphereIntel::memory_usage() { return FixNVE::memory_usage() + _nlocal_max * 12 * sizeof(double); } diff --git a/src/USER-INTEL/pair_buck_coul_cut_intel.cpp b/src/USER-INTEL/pair_buck_coul_cut_intel.cpp index b9d60d8ea..4f34a484c 100644 --- a/src/USER-INTEL/pair_buck_coul_cut_intel.cpp +++ b/src/USER-INTEL/pair_buck_coul_cut_intel.cpp @@ -1,556 +1,556 @@ /* -*- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Rodrigo Canales (RWTH Aachen University) ------------------------------------------------------------------------- */ -#include "math.h" -#include "stdio.h" -#include "stdlib.h" -#include "string.h" +#include +#include +#include +#include #include "pair_buck_coul_cut_intel.h" #include "atom.h" #include "comm.h" #include "force.h" #include "group.h" #include "kspace.h" #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" #include "math_const.h" #include "memory.h" #include "error.h" #include "suffix.h" #include "force.h" #include "modify.h" using namespace LAMMPS_NS; using namespace MathConst; #define C_FORCE_T typename ForceConst::c_force_t #define C_ENERGY_T typename ForceConst::c_energy_t #define C_CUT_T typename ForceConst::c_cut_t PairBuckCoulCutIntel::PairBuckCoulCutIntel(LAMMPS *lmp) : PairBuckCoulCut(lmp) { suffix_flag |= Suffix::INTEL; } PairBuckCoulCutIntel::~PairBuckCoulCutIntel() { } void PairBuckCoulCutIntel::compute(int eflag, int vflag) { if (fix->precision()==FixIntel::PREC_MODE_MIXED) compute(eflag, vflag, fix->get_mixed_buffers(), force_const_single); else if (fix->precision()==FixIntel::PREC_MODE_DOUBLE) compute(eflag, vflag, fix->get_double_buffers(), force_const_double); else compute(eflag, vflag, fix->get_single_buffers(), force_const_single); fix->balance_stamp(); vflag_fdotr = 0; } template void PairBuckCoulCutIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { if (eflag || vflag) { ev_setup(eflag,vflag); } else evflag = vflag_fdotr = 0; const int inum = list->inum; const int nthreads = comm->nthreads; const int host_start = fix->host_start_pair(); const int offload_end = fix->offload_end_pair(); const int ago = neighbor->ago; if (ago != 0 && fix->separate_buffers() == 0) { fix->start_watch(TIME_PACK); #if defined(_OPENMP) #pragma omp parallel default(none) shared(eflag,vflag,buffers,fc) #endif { int ifrom, ito, tid; IP_PRE_omp_range_id_align(ifrom, ito, tid, atom->nlocal + atom->nghost, nthreads, sizeof(ATOM_T)); buffers->thr_pack(ifrom,ito,ago); } fix->stop_watch(TIME_PACK); } if (evflag || vflag_fdotr) { int ovflag = 0; if (vflag_fdotr) ovflag = 2; else if (vflag) ovflag = 1; if (eflag) { if (force->newton_pair) { eval<1,1,1>(1, ovflag, buffers, fc, 0, offload_end); eval<1,1,1>(0, ovflag, buffers, fc, host_start, inum); } else { eval<1,1,0>(1, ovflag, buffers, fc, 0, offload_end); eval<1,1,0>(0, ovflag, buffers, fc, host_start, inum); } } else { if (force->newton_pair) { eval<1,0,1>(1, ovflag, buffers, fc, 0, offload_end); eval<1,0,1>(0, ovflag, buffers, fc, host_start, inum); } else { eval<1,0,0>(1, ovflag, buffers, fc, 0, offload_end); eval<1,0,0>(0, ovflag, buffers, fc, host_start, inum); } } } else { if (force->newton_pair) { eval<0,0,1>(1, 0, buffers, fc, 0, offload_end); eval<0,0,1>(0, 0, buffers, fc, host_start, inum); } else { eval<0,0,0>(1, 0, buffers, fc, 0, offload_end); eval<0,0,0>(0, 0, buffers, fc, host_start, inum); } } } /* ---------------------------------------------------------------------- */ template void PairBuckCoulCutIntel::eval(const int offload, const int vflag, IntelBuffers *buffers, const ForceConst &fc, const int astart, const int aend) { const int inum = aend - astart; if (inum == 0) return; int nlocal, nall, minlocal; fix->get_buffern(offload, nlocal, nall, minlocal); const int ago = neighbor->ago; IP_PRE_pack_separate_buffers(fix, buffers, ago, offload, nlocal, nall); ATOM_T * _noalias const x = buffers->get_x(offload); flt_t * _noalias const q = buffers->get_q(offload); const int * _noalias const numneigh = list->numneigh; const int * _noalias const cnumneigh = buffers->cnumneigh(list); const int * _noalias const firstneigh = buffers->firstneigh(list); const flt_t * _noalias const special_coul = fc.special_coul; const flt_t * _noalias const special_lj = fc.special_lj; const flt_t qqrd2e = force->qqrd2e; const C_FORCE_T * _noalias const c_force = fc.c_force[0]; const C_ENERGY_T * _noalias const c_energy = fc.c_energy[0]; const C_CUT_T * _noalias const c_cut = fc.c_cut[0]; const int ntypes = atom->ntypes + 1; const int eatom = this->eflag_atom; // Determine how much data to transfer int x_size, q_size, f_stride, ev_size, separate_flag; IP_PRE_get_transfern(ago, NEWTON_PAIR, EVFLAG, EFLAG, vflag, buffers, offload, fix, separate_flag, x_size, q_size, ev_size, f_stride); int tc; FORCE_T * _noalias f_start; acc_t * _noalias ev_global; IP_PRE_get_buffers(offload, buffers, fix, tc, f_start, ev_global); const int nthreads = tc; #ifdef _LMP_INTEL_OFFLOAD int *overflow = fix->get_off_overflow_flag(); double *timer_compute = fix->off_watch_pair(); // Redeclare as local variables for offload const int ncoulmask = this->ncoulmask; const int ncoulshiftbits = this->ncoulshiftbits; if (offload) fix->start_watch(TIME_OFFLOAD_LATENCY); #pragma offload target(mic:_cop) if(offload) \ in(special_lj,special_coul:length(0) alloc_if(0) free_if(0)) \ in(c_force, c_energy, c_cut:length(0) alloc_if(0) free_if(0)) \ in(firstneigh:length(0) alloc_if(0) free_if(0)) \ in(cnumneigh:length(0) alloc_if(0) free_if(0)) \ in(numneigh:length(0) alloc_if(0) free_if(0)) \ in(x:length(x_size) alloc_if(0) free_if(0)) \ in(q:length(q_size) alloc_if(0) free_if(0)) \ in(overflow:length(0) alloc_if(0) free_if(0)) \ in(astart,nthreads,qqrd2e,inum,nall,ntypes,vflag,eatom) \ in(f_stride,nlocal,minlocal,separate_flag,offload) \ out(f_start:length(f_stride) alloc_if(0) free_if(0)) \ out(ev_global:length(ev_size) alloc_if(0) free_if(0)) \ out(timer_compute:length(1) alloc_if(0) free_if(0)) \ signal(f_start) #endif { #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) *timer_compute = MIC_Wtime(); #endif IP_PRE_repack_for_offload(NEWTON_PAIR, separate_flag, nlocal, nall, f_stride, x, q); acc_t oevdwl, oecoul, ov0, ov1, ov2, ov3, ov4, ov5; if (EVFLAG) { oevdwl = oecoul = (acc_t)0; if (vflag) ov0 = ov1 = ov2 = ov3 = ov4 = ov5 = (acc_t)0; } // loop over neighbors of my atoms #if defined(_OPENMP) #pragma omp parallel default(none) \ shared(f_start,f_stride,nlocal,nall,minlocal) \ reduction(+:oevdwl,oecoul,ov0,ov1,ov2,ov3,ov4,ov5) #endif { int iifrom, iito, tid; IP_PRE_omp_range_id(iifrom, iito, tid, inum, nthreads); iifrom += astart; iito += astart; FORCE_T * _noalias const f = f_start - minlocal + (tid * f_stride); memset(f + minlocal, 0, f_stride * sizeof(FORCE_T)); for (int i = iifrom; i < iito; ++i) { const int itype = x[i].w; const int ptr_off = itype * ntypes; const C_FORCE_T * _noalias const c_forcei = c_force + ptr_off; const C_ENERGY_T * _noalias const c_energyi = c_energy + ptr_off; const C_CUT_T * _noalias const c_cuti = c_cut + ptr_off; const int * _noalias const jlist = firstneigh + cnumneigh[i]; const int jnum = numneigh[i]; acc_t fxtmp,fytmp,fztmp,fwtmp; acc_t sevdwl, secoul, sv0, sv1, sv2, sv3, sv4, sv5; const flt_t xtmp = x[i].x; const flt_t ytmp = x[i].y; const flt_t ztmp = x[i].z; const flt_t qtmp = q[i]; fxtmp = fytmp = fztmp = (acc_t)0; if (EVFLAG) { if (EFLAG) fwtmp = sevdwl = secoul = (acc_t)0; if (vflag==1) sv0 = sv1 = sv2 = sv3 = sv4 = sv5 = (acc_t)0; } #if defined(LMP_SIMD_COMPILER) #pragma vector aligned #pragma simd reduction(+:fxtmp, fytmp, fztmp, fwtmp, sevdwl, \ sv0, sv1, sv2, sv3, sv4, sv5) #endif for (int jj = 0; jj < jnum; jj++) { flt_t forcecoul, forcebuck, evdwl, ecoul; forcecoul = forcebuck = evdwl = ecoul = (flt_t)0.0; const int sbindex = jlist[jj] >> SBBITS & 3; const int j = jlist[jj] & NEIGHMASK; const flt_t delx = xtmp - x[j].x; const flt_t dely = ytmp - x[j].y; const flt_t delz = ztmp - x[j].z; const int jtype = x[j].w; const flt_t rsq = delx * delx + dely * dely + delz * delz; const flt_t r = sqrt(rsq); const flt_t r2inv = (flt_t)1.0 / rsq; #ifdef INTEL_VMASK if (rsq < c_cuti[jtype].cut_coulsq) { #endif forcecoul = qqrd2e * qtmp*q[j]/r; if (EFLAG) ecoul = forcecoul; if (sbindex){ const flt_t factor_coul = special_coul[sbindex]; forcecoul *= factor_coul; if(EFLAG) ecoul *= factor_coul; } #ifdef INTEL_VMASK } #else if (rsq >= c_cuti[jtype].cut_coulsq) { forcecoul = (flt_t)0.0; ecoul = (flt_t)0.0; } #endif #ifdef INTEL_VMASK if (rsq < c_cuti[jtype].cut_ljsq) { #endif flt_t r6inv = r2inv * r2inv * r2inv; flt_t rexp = exp(-r * c_forcei[jtype].rhoinv); forcebuck = r * rexp * c_forcei[jtype].buck1 - r6inv * c_forcei[jtype].buck2; if (EFLAG) evdwl = rexp * c_energyi[jtype].a - r6inv * c_energyi[jtype].c - c_energyi[jtype].offset; if (sbindex) { const flt_t factor_lj = special_lj[sbindex]; forcebuck *= factor_lj; if (EFLAG) evdwl *= factor_lj; } #ifdef INTEL_VMASK } #else if (rsq >= c_cuti[jtype].cut_ljsq) { forcebuck = (flt_t)0.0; evdwl = (flt_t)0.0; } #endif #ifdef INTEL_VMASK if (rsq < c_cuti[jtype].cutsq) { #endif const flt_t fpair = (forcecoul + forcebuck) * r2inv; fxtmp += delx * fpair; fytmp += dely * fpair; fztmp += delz * fpair; if (NEWTON_PAIR || j < nlocal) { f[j].x -= delx * fpair; f[j].y -= dely * fpair; f[j].z -= delz * fpair; } if (EVFLAG) { flt_t ev_pre = (flt_t)0; if (NEWTON_PAIR || i < nlocal) ev_pre += (flt_t)0.5; if (NEWTON_PAIR || j < nlocal) ev_pre += (flt_t)0.5; if (EFLAG) { sevdwl += ev_pre * evdwl; secoul += ev_pre * ecoul; if (eatom) { if (NEWTON_PAIR || i < nlocal) fwtmp += (flt_t)0.5 * evdwl + (flt_t)0.5 * ecoul; if (NEWTON_PAIR || j < nlocal) f[j].w += (flt_t)0.5 * evdwl + (flt_t)0.5 * ecoul; } } IP_PRE_ev_tally_nbor(vflag, ev_pre, fpair, delx, dely, delz); } #ifdef INTEL_VMASK } #endif } // for jj f[i].x += fxtmp; f[i].y += fytmp; f[i].z += fztmp; IP_PRE_ev_tally_atomq(EVFLAG, EFLAG, vflag, f, fwtmp); } // for ii #ifndef _LMP_INTEL_OFFLOAD if (vflag == 2) #endif { #if defined(_OPENMP) #pragma omp barrier #endif IP_PRE_fdotr_acc_force(NEWTON_PAIR, EVFLAG, EFLAG, vflag, eatom, nall, nlocal, minlocal, nthreads, f_start, f_stride, x, offload); } } // end of omp parallel region if (EVFLAG) { if (EFLAG) { ev_global[0] = oevdwl; ev_global[1] = oecoul; } if (vflag) { ev_global[2] = ov0; ev_global[3] = ov1; ev_global[4] = ov2; ev_global[5] = ov3; ev_global[6] = ov4; ev_global[7] = ov5; } } #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) *timer_compute = MIC_Wtime() - *timer_compute; #endif } // end of offload region if (offload) fix->stop_watch(TIME_OFFLOAD_LATENCY); else fix->stop_watch(TIME_HOST_PAIR); if (EVFLAG) fix->add_result_array(f_start, ev_global, offload, eatom, 0, vflag); else fix->add_result_array(f_start, 0, offload); } /* ---------------------------------------------------------------------- */ void PairBuckCoulCutIntel::init_style() { PairBuckCoulCut::init_style(); neighbor->requests[neighbor->nrequest-1]->intel = 1; int ifix = modify->find_fix("package_intel"); if (ifix < 0) error->all(FLERR, "The 'package intel' command is required for /intel styles"); fix = static_cast(modify->fix[ifix]); fix->pair_init_check(); #ifdef _LMP_INTEL_OFFLOAD _cop = fix->coprocessor_number(); #endif if (fix->precision() == FixIntel::PREC_MODE_MIXED) pack_force_const(force_const_single, fix->get_mixed_buffers()); else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) pack_force_const(force_const_double, fix->get_double_buffers()); else pack_force_const(force_const_single, fix->get_single_buffers()); } template void PairBuckCoulCutIntel::pack_force_const(ForceConst &fc, IntelBuffers *buffers) { int tp1 = atom->ntypes + 1; int ntable = 1; if (ncoultablebits) for (int i = 0; i < ncoultablebits; i++) ntable *= 2; fc.set_ntypes(tp1, ntable, memory, _cop); buffers->set_ntypes(tp1); flt_t **cutneighsq = buffers->get_cutneighsq(); // Repeat cutsq calculation because done after call to init_style double cut, cutneigh; for (int i = 1; i <= atom->ntypes; i++) { for (int j = i; j <= atom->ntypes; j++) { if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) { cut = init_one(i, j); cutneigh = cut + neighbor->skin; cutsq[i][j] = cutsq[j][i] = cut*cut; cutneighsq[i][j] = cutneighsq[j][i] = cutneigh * cutneigh; } } } for (int i = 0; i < 4; i++) { fc.special_lj[i] = force->special_lj[i]; fc.special_coul[i] = force->special_coul[i]; fc.special_coul[0] = 1.0; fc.special_lj[0] = 1.0; } for (int i = 0; i < tp1; i++) { for (int j = 0; j < tp1; j++) { fc.c_cut[i][j].cutsq = cutsq[i][j]; fc.c_cut[i][j].cut_ljsq = cut_ljsq[i][j]; fc.c_cut[i][j].cut_coulsq = cut_coulsq[i][j]; fc.c_force[i][j].buck1 = buck1[i][j]; fc.c_force[i][j].buck2 = buck2[i][j]; fc.c_force[i][j].rhoinv = rhoinv[i][j]; fc.c_energy[i][j].a = a[i][j]; fc.c_energy[i][j].c = c[i][j]; fc.c_energy[i][j].offset = offset[i][j]; } } #ifdef _LMP_INTEL_OFFLOAD if (_cop < 0) return; flt_t * special_lj = fc.special_lj; flt_t * special_coul = fc.special_coul; C_FORCE_T * c_force = fc.c_force[0]; C_ENERGY_T * c_energy = fc.c_energy[0]; C_CUT_T * c_cut = fc.c_cut[0]; flt_t * ocutneighsq = cutneighsq[0]; int tp1sq = tp1 * tp1; #pragma offload_transfer target(mic:_cop) \ in(special_lj, special_coul: length(4) alloc_if(0) free_if(0)) \ in(c_force, c_energy, c_cut: length(tp1sq) alloc_if(0) free_if(0)) \ in(ocutneighsq: length(tp1sq) alloc_if(0) free_if(0)) #endif } /* ---------------------------------------------------------------------- */ template void PairBuckCoulCutIntel::ForceConst::set_ntypes(const int ntypes, const int ntable, Memory *memory, const int cop) { if ( (ntypes != _ntypes || ntable != _ntable) ) { if (_ntypes > 0) { #ifdef _LMP_INTEL_OFFLOAD flt_t * ospecial_lj = special_lj; flt_t * ospecial_coul = special_coul; c_force_t * oc_force = c_force[0]; c_energy_t * oc_energy = c_energy[0]; c_cut_t * oc_cut = c_cut[0]; if (ospecial_lj != NULL && oc_force != NULL && oc_cut != NULL && oc_energy != NULL && ospecial_coul != NULL && _cop >= 0) { #pragma offload_transfer target(mic:cop) \ nocopy(ospecial_lj, ospecial_coul: alloc_if(0) free_if(1)) \ nocopy(oc_force, oc_energy: alloc_if(0) free_if(1)) \ nocopy(oc_cut: alloc_if(0) free_if(1)) } #endif _memory->destroy(c_force); _memory->destroy(c_energy); _memory->destroy(c_cut); } if (ntypes > 0) { _cop = cop; memory->create(c_force,ntypes,ntypes,"fc.c_force"); memory->create(c_energy,ntypes,ntypes,"fc.c_energy"); memory->create(c_cut,ntypes,ntypes,"fc.c_cut"); #ifdef _LMP_INTEL_OFFLOAD flt_t * ospecial_lj = special_lj; flt_t * ospecial_coul = special_coul; c_force_t * oc_force = c_force[0]; c_energy_t * oc_energy = c_energy[0]; c_cut_t * oc_cut = c_cut[0]; int tp1sq = ntypes*ntypes; if (ospecial_lj != NULL && oc_force != NULL && oc_cut != NULL && oc_energy != NULL && ospecial_coul != NULL && cop >= 0) { #pragma offload_transfer target(mic:cop) \ nocopy(ospecial_lj: length(4) alloc_if(1) free_if(0)) \ nocopy(ospecial_coul: length(4) alloc_if(1) free_if(0)) \ nocopy(oc_force: length(tp1sq) alloc_if(1) free_if(0)) \ nocopy(oc_energy: length(tp1sq) alloc_if(1) free_if(0)) \ nocopy(oc_cut: length(tp1sq) alloc_if(1) free_if(0)) } #endif } } _ntypes=ntypes; _ntable=ntable; _memory=memory; } diff --git a/src/USER-INTEL/pair_buck_coul_long_intel.cpp b/src/USER-INTEL/pair_buck_coul_long_intel.cpp index 5450d6ff3..9319f531e 100644 --- a/src/USER-INTEL/pair_buck_coul_long_intel.cpp +++ b/src/USER-INTEL/pair_buck_coul_long_intel.cpp @@ -1,657 +1,657 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Rodrigo Canales (RWTH Aachen University) ------------------------------------------------------------------------- */ -#include "math.h" -#include "stdio.h" -#include "stdlib.h" -#include "string.h" +#include +#include +#include +#include #include "pair_buck_coul_long_intel.h" #include "atom.h" #include "comm.h" #include "force.h" #include "group.h" #include "kspace.h" #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" #include "math_const.h" #include "memory.h" #include "error.h" #include "suffix.h" #include "force.h" #include "modify.h" using namespace LAMMPS_NS; using namespace MathConst; #define C_FORCE_T typename ForceConst::c_force_t #define C_ENERGY_T typename ForceConst::c_energy_t #define TABLE_T typename ForceConst::table_t PairBuckCoulLongIntel::PairBuckCoulLongIntel(LAMMPS *lmp) : PairBuckCoulLong(lmp) { suffix_flag |= Suffix::INTEL; } PairBuckCoulLongIntel::~PairBuckCoulLongIntel() { } void PairBuckCoulLongIntel::compute(int eflag, int vflag) { if (fix->precision()==FixIntel::PREC_MODE_MIXED) compute(eflag, vflag, fix->get_mixed_buffers(), force_const_single); else if (fix->precision()==FixIntel::PREC_MODE_DOUBLE) compute(eflag, vflag, fix->get_double_buffers(), force_const_double); else compute(eflag, vflag, fix->get_single_buffers(), force_const_single); fix->balance_stamp(); vflag_fdotr = 0; } template void PairBuckCoulLongIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { if (eflag || vflag) { ev_setup(eflag,vflag); } else evflag = vflag_fdotr = 0; const int inum = list->inum; const int nthreads = comm->nthreads; const int host_start = fix->host_start_pair(); const int offload_end = fix->offload_end_pair(); const int ago = neighbor->ago; if (_lrt == 0 && ago != 0 && fix->separate_buffers() == 0) { fix->start_watch(TIME_PACK); #if defined(_OPENMP) #pragma omp parallel default(none) shared(eflag,vflag,buffers,fc) #endif { int ifrom, ito, tid; IP_PRE_omp_range_id_align(ifrom, ito, tid, atom->nlocal + atom->nghost, nthreads, sizeof(ATOM_T)); buffers->thr_pack(ifrom,ito,ago); } fix->stop_watch(TIME_PACK); } if (evflag || vflag_fdotr) { int ovflag = 0; if (vflag_fdotr) ovflag = 2; else if (vflag) ovflag = 1; if (eflag) { if (force->newton_pair) { eval<1,1,1>(1, ovflag, buffers, fc, 0, offload_end); eval<1,1,1>(0, ovflag, buffers, fc, host_start, inum); } else { eval<1,1,0>(1, ovflag, buffers, fc, 0, offload_end); eval<1,1,0>(0, ovflag, buffers, fc, host_start, inum); } } else { if (force->newton_pair) { eval<1,0,1>(1, ovflag, buffers, fc, 0, offload_end); eval<1,0,1>(0, ovflag, buffers, fc, host_start, inum); } else { eval<1,0,0>(1, ovflag, buffers, fc, 0, offload_end); eval<1,0,0>(0, ovflag, buffers, fc, host_start, inum); } } } else { if (force->newton_pair) { eval<0,0,1>(1, 0, buffers, fc, 0, offload_end); eval<0,0,1>(0, 0, buffers, fc, host_start, inum); } else { eval<0,0,0>(1, 0, buffers, fc, 0, offload_end); eval<0,0,0>(0, 0, buffers, fc, host_start, inum); } } } /* ---------------------------------------------------------------------- */ template void PairBuckCoulLongIntel::eval(const int offload, const int vflag, IntelBuffers *buffers, const ForceConst &fc, const int astart, const int aend) { const int inum = aend - astart; if (inum == 0) return; int nlocal, nall, minlocal; fix->get_buffern(offload, nlocal, nall, minlocal); const int ago = neighbor->ago; IP_PRE_pack_separate_buffers(fix, buffers, ago, offload, nlocal, nall); ATOM_T * _noalias const x = buffers->get_x(offload); flt_t * _noalias const q = buffers->get_q(offload); const int * _noalias const numneigh = list->numneigh; const int * _noalias const cnumneigh = buffers->cnumneigh(list); const int * _noalias const firstneigh = buffers->firstneigh(list); const flt_t * _noalias const special_coul = fc.special_coul; const flt_t * _noalias const special_lj = fc.special_lj; const flt_t qqrd2e = force->qqrd2e; const C_FORCE_T * _noalias const c_force = fc.c_force[0]; const C_ENERGY_T * _noalias const c_energy = fc.c_energy[0]; const flt_t * _noalias const rho_inv = fc.rho_inv[0]; const TABLE_T * _noalias const table = fc.table; const flt_t * _noalias const etable = fc.etable; const flt_t * _noalias const detable = fc.detable; const flt_t * _noalias const ctable = fc.ctable; const flt_t * _noalias const dctable = fc.dctable; const flt_t g_ewald = fc.g_ewald; const flt_t tabinnersq = fc.tabinnersq; const int ntypes = atom->ntypes + 1; const int eatom = this->eflag_atom; // Determine how much data to transfer int x_size, q_size, f_stride, ev_size, separate_flag; IP_PRE_get_transfern(ago, NEWTON_PAIR, EVFLAG, EFLAG, vflag, buffers, offload, fix, separate_flag, x_size, q_size, ev_size, f_stride); int tc; FORCE_T * _noalias f_start; acc_t * _noalias ev_global; IP_PRE_get_buffers(offload, buffers, fix, tc, f_start, ev_global); const int nthreads = tc; #ifdef _LMP_INTEL_OFFLOAD int *overflow = fix->get_off_overflow_flag(); double *timer_compute = fix->off_watch_pair(); // Redeclare as local variables for offload const int ncoultablebits = this->ncoultablebits; const int ncoulmask = this->ncoulmask; const int ncoulshiftbits = this->ncoulshiftbits; #ifdef INTEL_ALLOW_TABLE #define ITABLE_IN in(table,etable,detable:length(0) alloc_if(0) free_if(0)) \ in(ctable,dctable:length(0) alloc_if(0) free_if(0)) \ in(ncoultablebits,tabinnersq,ncoulmask,ncoulshiftbits) #else #define ITABLE_IN #endif if (offload) fix->start_watch(TIME_OFFLOAD_LATENCY); #pragma offload target(mic:_cop) if(offload) \ in(special_lj,special_coul:length(0) alloc_if(0) free_if(0)) \ in(c_force, c_energy:length(0) alloc_if(0) free_if(0)) \ in(rho_inv:length(0) alloc_if(0) free_if(0)) \ in(firstneigh:length(0) alloc_if(0) free_if(0)) \ in(cnumneigh:length(0) alloc_if(0) free_if(0)) \ in(numneigh:length(0) alloc_if(0) free_if(0)) \ in(x:length(x_size) alloc_if(0) free_if(0)) \ in(q:length(q_size) alloc_if(0) free_if(0)) \ in(overflow:length(0) alloc_if(0) free_if(0)) \ in(astart,nthreads,qqrd2e,g_ewald,inum,nall,ntypes,vflag,eatom) \ in(f_stride,nlocal,minlocal,separate_flag,offload) \ out(f_start:length(f_stride) alloc_if(0) free_if(0)) \ out(ev_global:length(ev_size) alloc_if(0) free_if(0)) \ out(timer_compute:length(1) alloc_if(0) free_if(0)) \ ITABLE_IN signal(f_start) #endif { #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) *timer_compute = MIC_Wtime(); #endif IP_PRE_repack_for_offload(NEWTON_PAIR, separate_flag, nlocal, nall, f_stride, x, q); acc_t oevdwl, oecoul, ov0, ov1, ov2, ov3, ov4, ov5; if (EVFLAG) { oevdwl = oecoul = (acc_t)0; if (vflag) ov0 = ov1 = ov2 = ov3 = ov4 = ov5 = (acc_t)0; } // loop over neighbors of my atoms #if defined(_OPENMP) #pragma omp parallel default(none) \ shared(f_start,f_stride,nlocal,nall,minlocal) \ reduction(+:oevdwl,oecoul,ov0,ov1,ov2,ov3,ov4,ov5) #endif { int iifrom, iito, tid; IP_PRE_omp_range_id(iifrom, iito, tid, inum, nthreads); iifrom += astart; iito += astart; FORCE_T * _noalias const f = f_start - minlocal + (tid * f_stride); memset(f + minlocal, 0, f_stride * sizeof(FORCE_T)); for (int i = iifrom; i < iito; ++i) { const int itype = x[i].w; const int ptr_off = itype * ntypes; const C_FORCE_T * _noalias const c_forcei = c_force + ptr_off; const C_ENERGY_T * _noalias const c_energyi = c_energy + ptr_off; const flt_t * _noalias const rho_invi = rho_inv + ptr_off; const int * _noalias const jlist = firstneigh + cnumneigh[i]; const int jnum = numneigh[i]; acc_t fxtmp,fytmp,fztmp,fwtmp; acc_t sevdwl, secoul, sv0, sv1, sv2, sv3, sv4, sv5; const flt_t xtmp = x[i].x; const flt_t ytmp = x[i].y; const flt_t ztmp = x[i].z; const flt_t qtmp = q[i]; fxtmp = fytmp = fztmp = (acc_t)0; if (EVFLAG) { if (EFLAG) fwtmp = sevdwl = secoul = (acc_t)0; if (vflag==1) sv0 = sv1 = sv2 = sv3 = sv4 = sv5 = (acc_t)0; } #if defined(LMP_SIMD_COMPILER) #pragma vector aligned #pragma simd reduction(+:fxtmp, fytmp, fztmp, fwtmp, sevdwl, \ sv0, sv1, sv2, sv3, sv4, sv5) #endif for (int jj = 0; jj < jnum; jj++) { flt_t forcecoul, forcebuck, evdwl, ecoul; forcecoul = forcebuck = evdwl = ecoul = (flt_t)0.0; const int sbindex = jlist[jj] >> SBBITS & 3; const int j = jlist[jj] & NEIGHMASK; const flt_t delx = xtmp - x[j].x; const flt_t dely = ytmp - x[j].y; const flt_t delz = ztmp - x[j].z; const int jtype = x[j].w; const flt_t rsq = delx * delx + dely * dely + delz * delz; const flt_t r2inv = (flt_t)1.0 / rsq; const flt_t r = (flt_t)1.0 / sqrt(r2inv); #ifdef INTEL_VMASK if (rsq < c_forcei[jtype].cutsq) { #endif #ifdef INTEL_ALLOW_TABLE if (!ncoultablebits || rsq <= tabinnersq) { #endif const flt_t A1 = 0.254829592; const flt_t A2 = -0.284496736; const flt_t A3 = 1.421413741; const flt_t A4 = -1.453152027; const flt_t A5 = 1.061405429; const flt_t EWALD_F = 1.12837917; const flt_t INV_EWALD_P = 1.0 / 0.3275911; const flt_t grij = g_ewald * r; const flt_t expm2 = exp(-grij * grij); const flt_t t = INV_EWALD_P / (INV_EWALD_P + grij); const flt_t erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; const flt_t prefactor = qqrd2e * qtmp * q[j] / r; forcecoul = prefactor * (erfc + EWALD_F * grij * expm2); if (EFLAG) ecoul = prefactor * erfc; const flt_t adjust = ((flt_t)1.0 - special_coul[sbindex])* prefactor; forcecoul -= adjust; if (EFLAG) ecoul -= adjust; #ifdef INTEL_ALLOW_TABLE } else { float rsq_lookup = rsq; const int itable = (__intel_castf32_u32(rsq_lookup) & ncoulmask) >> ncoulshiftbits; const flt_t fraction = (rsq_lookup - table[itable].r) * table[itable].dr; const flt_t tablet = table[itable].f + fraction * table[itable].df; forcecoul = qtmp * q[j] * tablet; if (EFLAG) ecoul = qtmp * q[j] * (etable[itable] + fraction * detable[itable]); if (sbindex) { const flt_t table2 = ctable[itable] + fraction * dctable[itable]; const flt_t prefactor = qtmp * q[j] * table2; const flt_t adjust = ((flt_t)1.0 - special_coul[sbindex]) * prefactor; forcecoul -= adjust; if (EFLAG) ecoul -= adjust; } } #endif #ifdef INTEL_VMASK } #endif #ifdef INTEL_VMASK if (rsq < c_forcei[jtype].cut_ljsq) { #endif flt_t r6inv = r2inv * r2inv * r2inv; flt_t rexp = exp(-r * rho_invi[jtype]); forcebuck = r * rexp * c_forcei[jtype].buck1 - r6inv * c_forcei[jtype].buck2; if (EFLAG) evdwl = rexp * c_energyi[jtype].a - r6inv * c_energyi[jtype].c - c_energyi[jtype].offset; if (sbindex) { const flt_t factor_lj = special_lj[sbindex]; forcebuck *= factor_lj; if (EFLAG) evdwl *= factor_lj; } #ifdef INTEL_VMASK } #else if (rsq > c_forcei[jtype].cutsq) { forcecoul = (flt_t)0.0; ecoul = (flt_t)0.0; } if (rsq > c_forcei[jtype].cut_ljsq) { forcebuck = (flt_t)0.0; evdwl = (flt_t)0.0; } #endif #ifdef INTEL_VMASK if (rsq < c_forcei[jtype].cutsq) { #endif const flt_t fpair = (forcecoul + forcebuck) * r2inv; fxtmp += delx * fpair; fytmp += dely * fpair; fztmp += delz * fpair; if (NEWTON_PAIR || j < nlocal) { f[j].x -= delx * fpair; f[j].y -= dely * fpair; f[j].z -= delz * fpair; } if (EVFLAG) { flt_t ev_pre = (flt_t)0; if (NEWTON_PAIR || i < nlocal) ev_pre += (flt_t)0.5; if (NEWTON_PAIR || j < nlocal) ev_pre += (flt_t)0.5; if (EFLAG) { sevdwl += ev_pre * evdwl; secoul += ev_pre * ecoul; if (eatom) { if (NEWTON_PAIR || i < nlocal) fwtmp += (flt_t)0.5 * evdwl + (flt_t)0.5 * ecoul; if (NEWTON_PAIR || j < nlocal) f[j].w += (flt_t)0.5 * evdwl + (flt_t)0.5 * ecoul; } } IP_PRE_ev_tally_nbor(vflag, ev_pre, fpair, delx, dely, delz); } #ifdef INTEL_VMASK } #endif } // for jj f[i].x += fxtmp; f[i].y += fytmp; f[i].z += fztmp; IP_PRE_ev_tally_atomq(EVFLAG, EFLAG, vflag, f, fwtmp); } // for ii #ifndef _LMP_INTEL_OFFLOAD if (vflag == 2) #endif { #if defined(_OPENMP) #pragma omp barrier #endif IP_PRE_fdotr_acc_force(NEWTON_PAIR, EVFLAG, EFLAG, vflag, eatom, nall, nlocal, minlocal, nthreads, f_start, f_stride, x, offload); } } // end of omp parallel region if (EVFLAG) { if (EFLAG) { ev_global[0] = oevdwl; ev_global[1] = oecoul; } if (vflag) { ev_global[2] = ov0; ev_global[3] = ov1; ev_global[4] = ov2; ev_global[5] = ov3; ev_global[6] = ov4; ev_global[7] = ov5; } } #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) *timer_compute = MIC_Wtime() - *timer_compute; #endif } // end of offload region if (offload) fix->stop_watch(TIME_OFFLOAD_LATENCY); else fix->stop_watch(TIME_HOST_PAIR); if (EVFLAG) fix->add_result_array(f_start, ev_global, offload, eatom, 0, vflag); else fix->add_result_array(f_start, 0, offload); } /* ---------------------------------------------------------------------- */ void PairBuckCoulLongIntel::init_style() { PairBuckCoulLong::init_style(); neighbor->requests[neighbor->nrequest-1]->intel = 1; int ifix = modify->find_fix("package_intel"); if (ifix < 0) error->all(FLERR, "The 'package intel' command is required for /intel styles"); fix = static_cast(modify->fix[ifix]); fix->pair_init_check(); #ifdef _LMP_INTEL_OFFLOAD _cop = fix->coprocessor_number(); #endif if (fix->precision() == FixIntel::PREC_MODE_MIXED) pack_force_const(force_const_single, fix->get_mixed_buffers()); else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) pack_force_const(force_const_double, fix->get_double_buffers()); else pack_force_const(force_const_single, fix->get_single_buffers()); _lrt = fix->lrt(); } template void PairBuckCoulLongIntel::pack_force_const(ForceConst &fc, IntelBuffers *buffers) { int tp1 = atom->ntypes + 1; int ntable = 1; if (ncoultablebits) for (int i = 0; i < ncoultablebits; i++) ntable *= 2; fc.set_ntypes(tp1, ntable, memory, _cop); buffers->set_ntypes(tp1); flt_t **cutneighsq = buffers->get_cutneighsq(); // Repeat cutsq calculation because done after call to init_style double cut, cutneigh; for (int i = 1; i <= atom->ntypes; i++) { for (int j = i; j <= atom->ntypes; j++) { if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) { cut = init_one(i, j); cutneigh = cut + neighbor->skin; cutsq[i][j] = cutsq[j][i] = cut*cut; cutneighsq[i][j] = cutneighsq[j][i] = cutneigh * cutneigh; } } } fc.g_ewald = force->kspace->g_ewald; fc.tabinnersq = tabinnersq; for (int i = 0; i < 4; i++) { fc.special_lj[i] = force->special_lj[i]; fc.special_coul[i] = force->special_coul[i]; fc.special_coul[0] = 1.0; fc.special_lj[0] = 1.0; } for (int i = 0; i < tp1; i++) { for (int j = 0; j < tp1; j++) { fc.c_force[i][j].cutsq = cutsq[i][j]; fc.c_force[i][j].cut_ljsq = cut_ljsq[i][j]; fc.c_force[i][j].buck1 = buck1[i][j]; fc.c_force[i][j].buck2 = buck2[i][j]; fc.rho_inv[i][j] = rhoinv[i][j]; fc.c_energy[i][j].a = a[i][j]; fc.c_energy[i][j].c = c[i][j]; fc.c_energy[i][j].offset = offset[i][j]; fc.c_energy[i][j].pad = rhoinv[i][j]; } } if (ncoultablebits) { for (int i = 0; i < ntable; i++) { fc.table[i].r = rtable[i]; fc.table[i].dr = drtable[i]; fc.table[i].f = ftable[i]; fc.table[i].df = dftable[i]; fc.etable[i] = etable[i]; fc.detable[i] = detable[i]; fc.ctable[i] = ctable[i]; fc.dctable[i] = dctable[i]; } } #ifdef _LMP_INTEL_OFFLOAD if (_cop < 0) return; flt_t * special_lj = fc.special_lj; flt_t * special_coul = fc.special_coul; C_FORCE_T * c_force = fc.c_force[0]; C_ENERGY_T * c_energy = fc.c_energy[0]; TABLE_T * table = fc.table; flt_t * rho_inv = fc.rho_inv[0]; flt_t * etable = fc.etable; flt_t * detable = fc.detable; flt_t * ctable = fc.ctable; flt_t * dctable = fc.dctable; flt_t * ocutneighsq = cutneighsq[0]; int tp1sq = tp1 * tp1; #pragma offload_transfer target(mic:_cop) \ in(special_lj, special_coul: length(4) alloc_if(0) free_if(0)) \ in(c_force, c_energy: length(tp1sq) alloc_if(0) free_if(0)) \ in(rho_inv: length(tp1sq) alloc_if(0) free_if(0)) \ in(table: length(ntable) alloc_if(0) free_if(0)) \ in(etable,detable,ctable,dctable: length(ntable) alloc_if(0) free_if(0)) \ in(ocutneighsq: length(tp1sq) alloc_if(0) free_if(0)) #endif } /* ---------------------------------------------------------------------- */ template void PairBuckCoulLongIntel::ForceConst::set_ntypes(const int ntypes, const int ntable, Memory *memory, const int cop) { if ( (ntypes != _ntypes || ntable != _ntable) ) { if (_ntypes > 0) { #ifdef _LMP_INTEL_OFFLOAD flt_t * ospecial_lj = special_lj; flt_t * ospecial_coul = special_coul; c_force_t * oc_force = c_force[0]; c_energy_t * oc_energy = c_energy[0]; table_t * otable = table; flt_t * orho_inv = rho_inv[0]; flt_t * oetable = etable; flt_t * odetable = detable; flt_t * octable = ctable; flt_t * odctable = dctable; if (ospecial_lj != NULL && oc_force != NULL && orho_inv != NULL && oc_energy != NULL && otable != NULL && oetable != NULL && odetable != NULL && octable != NULL && odctable != NULL && ospecial_coul != NULL && _cop >= 0) { #pragma offload_transfer target(mic:cop) \ nocopy(ospecial_lj, ospecial_coul: alloc_if(0) free_if(1)) \ nocopy(oc_force, oc_energy: alloc_if(0) free_if(1)) \ nocopy(orho_inv: alloc_if(0) free_if(1)) \ nocopy(otable: alloc_if(0) free_if(1)) \ nocopy(oetable, odetable, octable, odctable: alloc_if(0) free_if(1)) } #endif _memory->destroy(c_force); _memory->destroy(c_energy); _memory->destroy(table); _memory->destroy(rho_inv); _memory->destroy(etable); _memory->destroy(detable); _memory->destroy(ctable); _memory->destroy(dctable); } if (ntypes > 0) { _cop = cop; memory->create(c_force,ntypes,ntypes,"fc.c_force"); memory->create(c_energy,ntypes,ntypes,"fc.c_energy"); memory->create(rho_inv,ntypes,ntypes,"fc.rho_inv"); memory->create(table,ntable,"pair:fc.table"); memory->create(etable,ntable,"pair:fc.etable"); memory->create(detable,ntable,"pair:fc.detable"); memory->create(ctable,ntable,"pair:fc.ctable"); memory->create(dctable,ntable,"pair:fc.dctable"); #ifdef _LMP_INTEL_OFFLOAD flt_t * ospecial_lj = special_lj; flt_t * ospecial_coul = special_coul; c_force_t * oc_force = c_force[0]; c_energy_t * oc_energy = c_energy[0]; table_t * otable = table; flt_t * orho_inv = rho_inv[0]; flt_t * oetable = etable; flt_t * odetable = detable; flt_t * octable = ctable; flt_t * odctable = dctable; int tp1sq = ntypes*ntypes; if (ospecial_lj != NULL && oc_force != NULL && orho_inv != NULL && oc_energy != NULL && otable !=NULL && oetable != NULL && odetable != NULL && octable != NULL && odctable != NULL && ospecial_coul != NULL && cop >= 0) { #pragma offload_transfer target(mic:cop) \ nocopy(ospecial_lj: length(4) alloc_if(1) free_if(0)) \ nocopy(ospecial_coul: length(4) alloc_if(1) free_if(0)) \ nocopy(oc_force: length(tp1sq) alloc_if(1) free_if(0)) \ nocopy(oc_energy: length(tp1sq) alloc_if(1) free_if(0)) \ nocopy(orho_inv: length(tp1sq) alloc_if(1) free_if(0)) \ nocopy(otable: length(ntable) alloc_if(1) free_if(0)) \ nocopy(oetable,odetable: length(ntable) alloc_if(1) free_if(0)) \ nocopy(octable,odctable: length(ntable) alloc_if(1) free_if(0)) } #endif } } _ntypes=ntypes; _ntable=ntable; _memory=memory; } diff --git a/src/USER-INTEL/pair_buck_intel.cpp b/src/USER-INTEL/pair_buck_intel.cpp index 5411661c5..4815d1e02 100644 --- a/src/USER-INTEL/pair_buck_intel.cpp +++ b/src/USER-INTEL/pair_buck_intel.cpp @@ -1,498 +1,498 @@ /* -*- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Rodrigo Canales (RWTH Aachen University) ------------------------------------------------------------------------- */ -#include "math.h" +#include #include "pair_buck_intel.h" #include "atom.h" #include "comm.h" #include "force.h" #include "group.h" #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" #include "math_const.h" #include "memory.h" #include "suffix.h" #include "force.h" #include "modify.h" using namespace LAMMPS_NS; using namespace MathConst; #define C_FORCE_T typename ForceConst::c_force_t #define C_ENERGY_T typename ForceConst::c_energy_t PairBuckIntel::PairBuckIntel(LAMMPS *lmp) : PairBuck(lmp) { suffix_flag |= Suffix::INTEL; } PairBuckIntel::~PairBuckIntel() { } void PairBuckIntel::compute(int eflag, int vflag) { if (fix->precision()==FixIntel::PREC_MODE_MIXED) compute(eflag, vflag, fix->get_mixed_buffers(), force_const_single); else if (fix->precision()==FixIntel::PREC_MODE_DOUBLE) compute(eflag, vflag, fix->get_double_buffers(), force_const_double); else compute(eflag, vflag, fix->get_single_buffers(), force_const_single); fix->balance_stamp(); vflag_fdotr = 0; } template void PairBuckIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { if (eflag || vflag) { ev_setup(eflag,vflag); } else evflag = vflag_fdotr = 0; const int inum = list->inum; const int nthreads = comm->nthreads; const int host_start = fix->host_start_pair(); const int offload_end = fix->offload_end_pair(); const int ago = neighbor->ago; if (ago != 0 && fix->separate_buffers() == 0) { fix->start_watch(TIME_PACK); #if defined(_OPENMP) #pragma omp parallel default(none) shared(eflag,vflag,buffers,fc) #endif { int ifrom, ito, tid; IP_PRE_omp_range_id_align(ifrom, ito, tid, atom->nlocal + atom->nghost, nthreads, sizeof(ATOM_T)); buffers->thr_pack(ifrom,ito,ago); } fix->stop_watch(TIME_PACK); } if (evflag || vflag_fdotr) { int ovflag = 0; if (vflag_fdotr) ovflag = 2; else if (vflag) ovflag = 1; if (eflag) { if (force->newton_pair) { eval<1,1,1>(1, ovflag, buffers, fc, 0, offload_end); eval<1,1,1>(0, ovflag, buffers, fc, host_start, inum); } else { eval<1,1,0>(1, ovflag, buffers, fc, 0, offload_end); eval<1,1,0>(0, ovflag, buffers, fc, host_start, inum); } } else { if (force->newton_pair) { eval<1,0,1>(1, ovflag, buffers, fc, 0, offload_end); eval<1,0,1>(0, ovflag, buffers, fc, host_start, inum); } else { eval<1,0,0>(1, ovflag, buffers, fc, 0, offload_end); eval<1,0,0>(0, ovflag, buffers, fc, host_start, inum); } } } else { if (force->newton_pair) { eval<0,0,1>(1, 0, buffers, fc, 0, offload_end); eval<0,0,1>(0, 0, buffers, fc, host_start, inum); } else { eval<0,0,0>(1, 0, buffers, fc, 0, offload_end); eval<0,0,0>(0, 0, buffers, fc, host_start, inum); } } } /* ---------------------------------------------------------------------- */ template void PairBuckIntel::eval(const int offload, const int vflag, IntelBuffers *buffers, const ForceConst &fc, const int astart, const int aend) { const int inum = aend - astart; if (inum == 0) return; int nlocal, nall, minlocal; fix->get_buffern(offload, nlocal, nall, minlocal); const int ago = neighbor->ago; IP_PRE_pack_separate_buffers(fix, buffers, ago, offload, nlocal, nall); ATOM_T * _noalias const x = buffers->get_x(offload); const int * _noalias const numneigh = list->numneigh; const int * _noalias const cnumneigh = buffers->cnumneigh(list); const int * _noalias const firstneigh = buffers->firstneigh(list); const flt_t * _noalias const special_lj = fc.special_lj; const C_FORCE_T * _noalias const c_force = fc.c_force[0]; const C_ENERGY_T * _noalias const c_energy = fc.c_energy[0]; const int ntypes = atom->ntypes + 1; const int eatom = this->eflag_atom; // Determine how much data to transfer int x_size, q_size, f_stride, ev_size, separate_flag; IP_PRE_get_transfern(ago, NEWTON_PAIR, EVFLAG, EFLAG, vflag, buffers, offload, fix, separate_flag, x_size, q_size, ev_size, f_stride); int tc; FORCE_T * _noalias f_start; acc_t * _noalias ev_global; IP_PRE_get_buffers(offload, buffers, fix, tc, f_start, ev_global); const int nthreads = tc; #ifdef _LMP_INTEL_OFFLOAD int *overflow = fix->get_off_overflow_flag(); double *timer_compute = fix->off_watch_pair(); // Redeclare as local variables for offload if (offload) fix->start_watch(TIME_OFFLOAD_LATENCY); #pragma offload target(mic:_cop) if(offload) \ in(special_lj:length(0) alloc_if(0) free_if(0)) \ in(c_force, c_energy:length(0) alloc_if(0) free_if(0)) \ in(firstneigh:length(0) alloc_if(0) free_if(0)) \ in(cnumneigh:length(0) alloc_if(0) free_if(0)) \ in(numneigh:length(0) alloc_if(0) free_if(0)) \ in(x:length(x_size) alloc_if(0) free_if(0)) \ in(overflow:length(0) alloc_if(0) free_if(0)) \ in(astart,nthreads,inum,nall,ntypes,vflag,eatom) \ in(f_stride,nlocal,minlocal,separate_flag,offload) \ out(f_start:length(f_stride) alloc_if(0) free_if(0)) \ out(ev_global:length(ev_size) alloc_if(0) free_if(0)) \ out(timer_compute:length(1) alloc_if(0) free_if(0)) \ signal(f_start) #endif { #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) *timer_compute = MIC_Wtime(); #endif IP_PRE_repack_for_offload(NEWTON_PAIR, separate_flag, nlocal, nall, f_stride, x, 0); acc_t oevdwl, ov0, ov1, ov2, ov3, ov4, ov5; if (EVFLAG) { oevdwl = (acc_t)0; if (vflag) ov0 = ov1 = ov2 = ov3 = ov4 = ov5 = (acc_t)0; } // loop over neighbors of my atoms #if defined(_OPENMP) #pragma omp parallel default(none) \ shared(f_start,f_stride,nlocal,nall,minlocal) \ reduction(+:oevdwl,ov0,ov1,ov2,ov3,ov4,ov5) #endif { int iifrom, iito, tid; IP_PRE_omp_range_id(iifrom, iito, tid, inum, nthreads); iifrom += astart; iito += astart; FORCE_T * _noalias const f = f_start - minlocal + (tid * f_stride); memset(f + minlocal, 0, f_stride * sizeof(FORCE_T)); for (int i = iifrom; i < iito; ++i) { const int itype = x[i].w; const int ptr_off = itype * ntypes; const C_FORCE_T * _noalias const c_forcei = c_force + ptr_off; const C_ENERGY_T * _noalias const c_energyi = c_energy + ptr_off; const int * _noalias const jlist = firstneigh + cnumneigh[i]; const int jnum = numneigh[i]; acc_t fxtmp,fytmp,fztmp,fwtmp; acc_t sevdwl, sv0, sv1, sv2, sv3, sv4, sv5; const flt_t xtmp = x[i].x; const flt_t ytmp = x[i].y; const flt_t ztmp = x[i].z; fxtmp = fytmp = fztmp = (acc_t)0; if (EVFLAG) { if (EFLAG) fwtmp = sevdwl = (acc_t)0; if (vflag==1) sv0 = sv1 = sv2 = sv3 = sv4 = sv5 = (acc_t)0; } #if defined(LMP_SIMD_COMPILER) #pragma vector aligned #pragma simd reduction(+:fxtmp, fytmp, fztmp, fwtmp, sevdwl, \ sv0, sv1, sv2, sv3, sv4, sv5) #endif for (int jj = 0; jj < jnum; jj++) { flt_t forcebuck, evdwl; forcebuck = evdwl = (flt_t)0.0; const int sbindex = jlist[jj] >> SBBITS & 3; const int j = jlist[jj] & NEIGHMASK; const flt_t delx = xtmp - x[j].x; const flt_t dely = ytmp - x[j].y; const flt_t delz = ztmp - x[j].z; const int jtype = x[j].w; const flt_t rsq = delx * delx + dely * dely + delz * delz; const flt_t r = sqrt(rsq); const flt_t r2inv = (flt_t)1.0 / rsq; #ifdef INTEL_VMASK if (rsq < c_forcei[jtype].cutsq) { #endif const flt_t r6inv = r2inv * r2inv * r2inv; const flt_t rexp = exp(-r * c_forcei[jtype].rhoinv); forcebuck = r * rexp * c_forcei[jtype].buck1 - r6inv * c_forcei[jtype].buck2; #ifndef INTEL_VMASK if (rsq > c_forcei[jtype].cutsq) forcebuck =(flt_t)0.0; #endif if (EFLAG) { evdwl = rexp * c_energyi[jtype].a - r6inv * c_energyi[jtype].c - c_energyi[jtype].offset; #ifndef INTEL_VMASK if (rsq > c_forcei[jtype].cutsq) evdwl =(flt_t)0.0; #endif } if (sbindex) { const flt_t factor_lj = special_lj[sbindex]; forcebuck *= factor_lj; if (EFLAG) evdwl *= factor_lj; } const flt_t fpair = forcebuck * r2inv; fxtmp += delx * fpair; fytmp += dely * fpair; fztmp += delz * fpair; if (NEWTON_PAIR || j < nlocal) { f[j].x -= delx * fpair; f[j].y -= dely * fpair; f[j].z -= delz * fpair; } if (EVFLAG) { flt_t ev_pre = (flt_t)0; if (NEWTON_PAIR || i < nlocal) ev_pre += (flt_t)0.5; if (NEWTON_PAIR || j < nlocal) ev_pre += (flt_t)0.5; if (EFLAG) { sevdwl += ev_pre * evdwl; if (eatom) { if (NEWTON_PAIR || i < nlocal) fwtmp += (flt_t)0.5 * evdwl; if (NEWTON_PAIR || j < nlocal) f[j].w += (flt_t)0.5 * evdwl; } } IP_PRE_ev_tally_nbor(vflag, ev_pre, fpair, delx, dely, delz); } #ifdef INTEL_VMASK } #endif } // for jj f[i].x += fxtmp; f[i].y += fytmp; f[i].z += fztmp; IP_PRE_ev_tally_atom(EVFLAG, EFLAG, vflag, f, fwtmp); } // for ii #ifndef _LMP_INTEL_OFFLOAD if (vflag == 2) #endif { #if defined(_OPENMP) #pragma omp barrier #endif IP_PRE_fdotr_acc_force(NEWTON_PAIR, EVFLAG, EFLAG, vflag, eatom, nall, nlocal, minlocal, nthreads, f_start, f_stride, x, offload); } } // end of omp parallel region if (EVFLAG) { if (EFLAG) { ev_global[0] = oevdwl; ev_global[1] = (acc_t)0; } if (vflag) { ev_global[2] = ov0; ev_global[3] = ov1; ev_global[4] = ov2; ev_global[5] = ov3; ev_global[6] = ov4; ev_global[7] = ov5; } } #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) *timer_compute = MIC_Wtime() - *timer_compute; #endif } // end of offload region if (offload) fix->stop_watch(TIME_OFFLOAD_LATENCY); else fix->stop_watch(TIME_HOST_PAIR); if (EVFLAG) fix->add_result_array(f_start, ev_global, offload, eatom, 0, vflag); else fix->add_result_array(f_start, 0, offload); } void PairBuckIntel::init_style() { PairBuck::init_style(); neighbor->requests[neighbor->nrequest-1]->intel = 1; int ifix = modify->find_fix("package_intel"); if (ifix < 0) error->all(FLERR, "The 'package intel' command is required for /intel styles"); fix = static_cast(modify->fix[ifix]); fix->pair_init_check(); #ifdef _LMP_INTEL_OFFLOAD _cop = fix->coprocessor_number(); #endif if (fix->precision() == FixIntel::PREC_MODE_MIXED) pack_force_const(force_const_single, fix->get_mixed_buffers()); else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) pack_force_const(force_const_double, fix->get_double_buffers()); else pack_force_const(force_const_single, fix->get_single_buffers()); } template void PairBuckIntel::pack_force_const(ForceConst &fc, IntelBuffers *buffers) { int tp1 = atom->ntypes + 1; fc.set_ntypes(tp1, memory, _cop); buffers->set_ntypes(tp1); flt_t **cutneighsq = buffers->get_cutneighsq(); // Repeat cutsq calculation because done after call to init_style double cut, cutneigh; for (int i = 1; i <= atom->ntypes; i++) { for (int j = i; j <= atom->ntypes; j++) { if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) { cut = init_one(i, j); cutneigh = cut + neighbor->skin; cutsq[i][j] = cutsq[j][i] = cut*cut; cutneighsq[i][j] = cutneighsq[j][i] = cutneigh * cutneigh; } } } for (int i = 0; i < 4; i++) { fc.special_lj[i] = force->special_lj[i]; fc.special_lj[0] = 1.0; } for (int i = 0; i < tp1; i++) { for (int j = 0; j < tp1; j++) { fc.c_force[i][j].buck1 = buck1[i][j]; fc.c_force[i][j].buck2 = buck2[i][j]; fc.c_force[i][j].rhoinv = rhoinv[i][j]; fc.c_force[i][j].cutsq = cutsq[i][j]; fc.c_energy[i][j].a = a[i][j]; fc.c_energy[i][j].c = c[i][j]; fc.c_energy[i][j].offset = offset[i][j]; } } #ifdef _LMP_INTEL_OFFLOAD if (_cop < 0) return; flt_t * special_lj = fc.special_lj; C_FORCE_T * c_force = fc.c_force[0]; C_ENERGY_T * c_energy = fc.c_energy[0]; flt_t * ocutneighsq = cutneighsq[0]; int tp1sq = tp1 * tp1; #pragma offload_transfer target(mic:_cop) \ in(special_lj: length(4) alloc_if(0) free_if(0)) \ in(c_force, c_energy: length(tp1sq) alloc_if(0) free_if(0)) \ in(ocutneighsq: length(tp1sq) alloc_if(0) free_if(0)) #endif } /* ---------------------------------------------------------------------- */ template void PairBuckIntel::ForceConst::set_ntypes(const int ntypes, Memory *memory, const int cop) { if ( (ntypes != _ntypes ) ) { if (_ntypes > 0) { #ifdef _LMP_INTEL_OFFLOAD flt_t * ospecial_lj = special_lj; c_force_t * oc_force = c_force[0]; c_energy_t * oc_energy = c_energy[0]; if (ospecial_lj != NULL && oc_force != NULL && oc_energy != NULL && _cop >= 0) { #pragma offload_transfer target(mic:cop) \ nocopy(ospecial_lj: alloc_if(0) free_if(1)) \ nocopy(oc_force, oc_energy: alloc_if(0) free_if(1)) } #endif _memory->destroy(c_force); _memory->destroy(c_energy); } if (ntypes > 0) { _cop = cop; memory->create(c_force,ntypes,ntypes,"fc.c_force"); memory->create(c_energy,ntypes,ntypes,"fc.c_energy"); #ifdef _LMP_INTEL_OFFLOAD flt_t * ospecial_lj = special_lj; c_force_t * oc_force = c_force[0]; c_energy_t * oc_energy = c_energy[0]; int tp1sq = ntypes*ntypes; if (ospecial_lj != NULL && oc_force != NULL && oc_energy != NULL && cop >= 0) { #pragma offload_transfer target(mic:cop) \ nocopy(ospecial_lj: length(4) alloc_if(1) free_if(0)) \ nocopy(oc_force: length(tp1sq) alloc_if(1) free_if(0)) \ nocopy(oc_energy: length(tp1sq) alloc_if(1) free_if(0)) } #endif } } _ntypes=ntypes; _memory=memory; } diff --git a/src/USER-INTEL/pair_tersoff_intel.cpp b/src/USER-INTEL/pair_tersoff_intel.cpp index 0c07be463..88354ec4d 100644 --- a/src/USER-INTEL/pair_tersoff_intel.cpp +++ b/src/USER-INTEL/pair_tersoff_intel.cpp @@ -1,1504 +1,1504 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Markus Höhnerbach (RWTH) ------------------------------------------------------------------------- */ -#include "math.h" -#include "stdio.h" -#include "stdlib.h" -#include "string.h" +#include +#include +#include +#include #include "pair_tersoff_intel.h" #include "atom.h" #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" #include "force.h" #include "comm.h" #include "memory.h" #include "error.h" // Currently Intel compiler is required for this pair style. // For convenience, base class routines are called if not using Intel compiler. #ifndef __INTEL_COMPILER using namespace LAMMPS_NS; PairTersoffIntel::PairTersoffIntel(LAMMPS *lmp) : PairTersoff(lmp) { } void PairTersoffIntel::compute(int eflag, int vflag) { PairTersoff::compute(eflag, vflag); } void PairTersoffIntel::init_style() { if (comm->me == 0) { error->warning(FLERR, "Tersoff/intel currently requires intel compiler. " "Using MANYBODY version."); } PairTersoff::init_style(); } #else #ifdef _LMP_INTEL_OFFLOAD #pragma offload_attribute(push,target(mic)) #endif #include "intel_intrinsics.h" #include "math_const.h" #ifdef _LMP_INTEL_OFFLOAD #pragma offload_attribute(pop) #endif #include "group.h" #include "kspace.h" #include "modify.h" #include "suffix.h" using namespace LAMMPS_NS; using namespace MathConst; /* ---------------------------------------------------------------------- */ PairTersoffIntel::PairTersoffIntel(LAMMPS *lmp) : PairTersoff(lmp) { suffix_flag |= Suffix::INTEL; respa_enable = 0; } /* ---------------------------------------------------------------------- */ // Dispatch the requested precision void PairTersoffIntel::compute(int eflag, int vflag) { if (fix->precision()==FixIntel::PREC_MODE_MIXED) { compute(eflag, vflag, fix->get_mixed_buffers(), force_const_single); } else if (fix->precision()==FixIntel::PREC_MODE_DOUBLE) { compute(eflag, vflag, fix->get_double_buffers(), force_const_double); } else { compute(eflag, vflag, fix->get_single_buffers(), force_const_single); } fix->balance_stamp(); vflag_fdotr = 0; } // Dispatch the extent of computation: // do we need to calculate energy/virial template void PairTersoffIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { if (eflag || vflag) { ev_setup(eflag,vflag); } else evflag = vflag_fdotr = 0; const int inum = list->inum; const int nthreads = comm->nthreads; const int host_start = fix->host_start_pair(); const int offload_end = fix->offload_end_pair(); const int ago = neighbor->ago; if (ago != 0 && fix->separate_buffers() == 0) { fix->start_watch(TIME_PACK); #if defined(_OPENMP) #pragma omp parallel default(none) shared(eflag,vflag,buffers,fc) #endif { int ifrom, ito, tid; IP_PRE_omp_range_id_align(ifrom, ito, tid, atom->nlocal + atom->nghost, nthreads, sizeof(ATOM_T)); buffers->thr_pack(ifrom,ito,ago); } fix->stop_watch(TIME_PACK); } if (evflag || vflag_fdotr) { int ovflag = 0; if (vflag_fdotr) ovflag = 2; else if (vflag) ovflag = 1; if (eflag) { eval<1,1,1>(1, ovflag, buffers, fc, 0, offload_end); eval<1,1,1>(0, ovflag, buffers, fc, host_start, inum); } else { eval<1,0,1>(1, ovflag, buffers, fc, 0, offload_end); eval<1,0,1>(0, ovflag, buffers, fc, host_start, inum); } } else { eval<0,0,1>(1, 0, buffers, fc, 0, offload_end); eval<0,0,1>(0, 0, buffers, fc, host_start, inum); } } #ifdef _LMP_INTEL_OFFLOAD #pragma offload_attribute(push, target(mic)) #endif // The complete Tersoff computation kernel is encapsulated here // everything is static, the class just serves as a unit of organization template struct IntelKernelTersoff : public lmp_intel::vector_routines { // instantiate the vector library and import the types typedef typename lmp_intel::vector_routines v; typedef typename v::fvec fvec; typedef typename v::ivec ivec; typedef typename v::bvec bvec; typedef typename v::avec avec; typedef typename v::iarr iarr; typedef typename v::farr farr; typedef typename v::aarr aarr; typedef typename PairTersoffIntel::ForceConst::c_inner_t c_inner_t; typedef typename PairTersoffIntel::ForceConst::c_outer_t c_outer_t; // for descriptions of these methods, please have a look at the original code // what's done in here is that they are inlined and vectorized // attractive() also provides an option to compute zeta as well static fvec zeta_vector( const c_inner_t * param, ivec xjw, bvec mask, fvec vrij, fvec rsq2, fvec vdijx, fvec vdijy, fvec vdijz, fvec dikx, fvec diky, fvec dikz ); static void force_zeta_vector( const c_outer_t * param, ivec xjw, bvec mask, fvec vrijsq, fvec vzeta_ij, fvec *vfpair, fvec *vprefactor, int EVDWL, fvec *vevdwl, bvec vmask_repulsive ); template static void attractive_vector( const c_inner_t * param, ivec xjw, bvec mask, fvec vprefactor, fvec vrijsq, fvec rsq2, fvec vdijx, fvec vdijy, fvec vdijz, fvec dikx, fvec diky, fvec dikz, fvec *fix, fvec *fiy, fvec *fiz, fvec *fjx, fvec *fjy, fvec *fjz, fvec *fkx, fvec *fky, fvec *fkz, fvec *zeta ); // perform the actual computation template static void kernel( int iito, int iifrom, int eatom, int vflag, const int * _noalias const numneigh, const int * _noalias const numneighhalf, const int * _noalias const cnumneigh, const int * _noalias const firstneigh, int ntypes, typename IntelBuffers::atom_t * _noalias const x, const c_inner_t * _noalias const c_inner, const c_outer_t * _noalias const c_outer, typename IntelBuffers::vec3_acc_t * _noalias const f, acc_t *evdwl, acc_t *ov0, acc_t * ov1, acc_t *ov2, acc_t* ov3, acc_t *ov4, acc_t *ov5 ); // perform one step of calculation, pass in i-j pairs of atoms (is, js) template static void kernel_step( int eatom, int vflag, const int * _noalias const numneigh, const int * _noalias const cnumneigh, const int * _noalias const firstneigh, int ntypes, typename IntelBuffers::atom_t * _noalias const x, const c_inner_t * _noalias const c_inner, const c_outer_t * _noalias const c_outer, typename IntelBuffers::vec3_acc_t * _noalias const f, avec *vsevdwl, avec *vsv0, avec * vsv1, avec *vsv2, avec* vsv3, avec *vsv4, avec *vsv5, int compress_idx, iarr is, iarr js, bvec vmask_repulsive ); // perform one step of calculation, as opposed to the previous method now // with fixed i and a number of js template static void kernel_step_const_i( int eatom, int vflag, const int * _noalias const numneigh, const int * _noalias const cnumneigh, const int * _noalias const firstneigh, int ntypes, typename IntelBuffers::atom_t * _noalias const x, const c_inner_t * _noalias const c_inner, const c_outer_t * _noalias const c_outer, typename IntelBuffers::vec3_acc_t * _noalias const f, avec *vsevdwl, avec *vsv0, avec *vsv1, avec *vsv2, avec *vsv3, avec *vsv4, avec *vsv5, int compress_idx, int i, iarr js, bvec vmask_repulsive ); }; #ifdef _LMP_INTEL_OFFLOAD #pragma offload_attribute(pop) #endif /* ---------------------------------------------------------------------- */ // Dispatch to correct kernel instatiation and perform all the work neccesary // for offloading. In this routine we enter the Phi. // This method is nearly identical to what happens in the other /intel styles template void PairTersoffIntel::eval(const int offload, const int vflag, IntelBuffers *buffers, const ForceConst &fc, const int astart, const int aend) { const int inum = aend - astart; if (inum == 0) return; int nlocal, nall, minlocal; fix->get_buffern(offload, nlocal, nall, minlocal); const int ago = neighbor->ago; IP_PRE_pack_separate_buffers(fix, buffers, ago, offload, nlocal, nall); ATOM_T * _noalias const x = buffers->get_x(offload); tagint * _noalias tag = this->atom->tag; flt_t * _noalias const q = buffers->get_q(offload); const int * _noalias const numneigh = list->numneigh; const int * _noalias const cnumneigh = buffers->cnumneigh(list); const int * _noalias const numneighhalf = buffers->get_atombin(); const int * _noalias const firstneigh = buffers->firstneigh(list); typedef typename ForceConst::c_inner_t c_inner_t; typedef typename ForceConst::c_outer_t c_outer_t; typedef typename ForceConst::c_cutoff_t c_cutoff_t; const c_outer_t * _noalias const c_outer = fc.c_outer[0]; const c_inner_t * _noalias const c_inner = fc.c_inner[0][0]; const c_cutoff_t * _noalias const c_inner_cutoff = fc.c_cutoff_inner[0][0]; const int ntypes = atom->ntypes + 1; const int eatom = this->eflag_atom; // Determine how much data to transfer int x_size, q_size, f_stride, ev_size, separate_flag; IP_PRE_get_transfern(ago, NEWTON_PAIR, EVFLAG, EFLAG, vflag, buffers, offload, fix, separate_flag, x_size, q_size, ev_size, f_stride); int tc; FORCE_T * _noalias f_start; acc_t * _noalias ev_global; IP_PRE_get_buffers(offload, buffers, fix, tc, f_start, ev_global); const int nthreads = tc; #ifdef _LMP_INTEL_OFFLOAD int *overflow = fix->get_off_overflow_flag(); double *timer_compute = fix->off_watch_pair(); if (offload) fix->start_watch(TIME_OFFLOAD_LATENCY); #pragma offload target(mic:_cop) if(offload) \ in(c_inner, c_outer :length(0) alloc_if(0) free_if(0)) \ in(c_inner_cutoff :length(0) alloc_if(0) free_if(0)) \ in(firstneigh:length(0) alloc_if(0) free_if(0)) \ in(cnumneigh:length(0) alloc_if(0) free_if(0)) \ in(numneigh:length(0) alloc_if(0) free_if(0)) \ in(numneighhalf:length(0) alloc_if(0) free_if(0)) \ in(x:length(x_size) alloc_if(0) free_if(0)) \ in(overflow:length(0) alloc_if(0) free_if(0)) \ in(astart,nthreads,inum,nall,ntypes,vflag,eatom) \ in(f_stride,nlocal,minlocal,separate_flag,offload) \ out(f_start:length(f_stride) alloc_if(0) free_if(0)) \ out(ev_global:length(ev_size) alloc_if(0) free_if(0)) \ out(timer_compute:length(1) alloc_if(0) free_if(0)) \ signal(f_start) #endif { #ifdef _LMP_INTEL_OFFLOAD #ifdef __MIC__ *timer_compute = MIC_Wtime(); #endif #endif IP_PRE_repack_for_offload(NEWTON_PAIR, separate_flag, nlocal, nall, f_stride, x, 0); acc_t oevdwl, oecoul, ov0, ov1, ov2, ov3, ov4, ov5; if (EVFLAG) { oevdwl = oecoul = (acc_t)0; if (vflag) ov0 = ov1 = ov2 = ov3 = ov4 = ov5 = (acc_t)0; } // loop over neighbors of my atoms #if defined(_OPENMP) #pragma omp parallel default(none) \ shared(f_start,f_stride,nlocal,nall,minlocal) \ reduction(+:oevdwl,oecoul,ov0,ov1,ov2,ov3,ov4,ov5) #endif { int iifrom, iito, tid; IP_PRE_omp_range_id(iifrom, iito, tid, inum, nthreads); iifrom += astart; iito += astart; FORCE_T * _noalias const f = f_start - minlocal + (tid * f_stride); memset(f + minlocal, 0, f_stride * sizeof(FORCE_T)); { acc_t sevdwl, sv0, sv1, sv2, sv3, sv4, sv5; sevdwl = sv0 = sv1 = sv2 = sv3 = sv4 = sv5 = 0.; #define ARGS iito, iifrom, eatom, vflag, numneigh, numneighhalf, cnumneigh, \ firstneigh, ntypes, x, c_inner, c_outer, f, &sevdwl, &sv0, &sv1, &sv2, &sv3, &sv4, &sv5 // Pick the variable i algorithm under specific conditions // do use scalar algorithm with very short vectors int VL = lmp_intel::vector_routines::VL; bool pack_i = VL >= 8 && lmp_intel::vector_traits::support_integer_and_gather_ops; bool use_scalar = VL < 4; if (use_scalar) { IntelKernelTersoff::kernel(ARGS); } else if (pack_i) { IntelKernelTersoff::kernel(ARGS); } else { IntelKernelTersoff::kernel(ARGS); } if (EVFLAG) { if (EFLAG) oevdwl += sevdwl; if (vflag == 1) { ov0 += sv0; ov1 += sv1; ov2 += sv2; ov3 += sv3; ov4 += sv4; ov5 += sv5; } } } #ifndef _LMP_INTEL_OFFLOAD if (vflag == 2) #endif { #if defined(_OPENMP) #pragma omp barrier #endif IP_PRE_fdotr_acc_force(NEWTON_PAIR, EVFLAG, EFLAG, vflag, eatom, nall, nlocal, minlocal, nthreads, f_start, f_stride, x, offload); } } // end of omp parallel region if (EVFLAG) { if (EFLAG) { ev_global[0] = oevdwl; ev_global[1] = 0.0; } if (vflag) { ev_global[2] = ov0; ev_global[3] = ov1; ev_global[4] = ov2; ev_global[5] = ov3; ev_global[6] = ov4; ev_global[7] = ov5; } } #ifdef _LMP_INTEL_OFFLOAD #ifdef __MIC__ *timer_compute = MIC_Wtime() - *timer_compute; #endif #endif } // end of offload region if (offload) fix->stop_watch(TIME_OFFLOAD_LATENCY); else fix->stop_watch(TIME_HOST_PAIR); if (EVFLAG) fix->add_result_array(f_start, ev_global, offload, eatom, 0, vflag); else fix->add_result_array(f_start, 0, offload); } /* ---------------------------------------------------------------------- init specific to this pair style ------------------------------------------------------------------------- */ // As in any other /intel pair style void PairTersoffIntel::init_style() { if (atom->tag_enable == 0) error->all(FLERR,"Pair style Tersoff requires atom IDs"); if (force->newton_pair == 0) error->all(FLERR,"Pair style Tersoff requires newton pair on"); // need a full neighbor list int irequest = neighbor->request(this); neighbor->requests[irequest]->half = 0; neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->intel = 1; int ifix = modify->find_fix("package_intel"); if (ifix < 0) error->all(FLERR, "The 'package intel' command is required for /intel styles"); fix = static_cast(modify->fix[ifix]); fix->pair_init_check(); #ifdef _LMP_INTEL_OFFLOAD _cop = fix->coprocessor_number(); #endif if (fix->precision() == FixIntel::PREC_MODE_MIXED) { pack_force_const(force_const_single, fix->get_mixed_buffers()); fix->get_mixed_buffers()->need_tag(1); } else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) { fix->get_double_buffers()->need_tag(1); pack_force_const(force_const_double, fix->get_double_buffers()); } else { pack_force_const(force_const_single, fix->get_single_buffers()); fix->get_single_buffers()->need_tag(1); } } // As in any other /intel pair style template void PairTersoffIntel::pack_force_const(ForceConst &fc, IntelBuffers *buffers) { int tp1 = atom->ntypes + 1; fc.set_ntypes(tp1, memory, _cop); buffers->set_ntypes(tp1); flt_t **cutneighsq = buffers->get_cutneighsq(); // Repeat cutsq calculation because done after call to init_style double cut, cutneigh; for (int i = 1; i <= atom->ntypes; i++) { for (int j = i; j <= atom->ntypes; j++) { if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) { cut = init_one(i, j); cutneigh = cut + neighbor->skin; cutsq[i][j] = cutsq[j][i] = cut*cut; cutneighsq[i][j] = cutneighsq[j][i] = cutneigh * cutneigh; } } } for (int i = 1; i < tp1; i++) { for (int j = 1; j < tp1; j++) { fc.c_inner_loop[i][j][0].d2 = 1.0; fc.c_inner_loop[i][0][j].d2 = 1.0; fc.c_inner_loop[0][i][j].d2 = 1.0; for (int k = 1; k < tp1; k++) { Param * param = ¶ms[elem2param[map[i]][map[j]][map[k]]]; fc.c_cutoff_inner[i][k][j].cutsq = static_cast(param->cutsq); fc.c_inner_loop[i][j][k].lam3 = static_cast(param->lam3); fc.c_inner_loop[i][j][k].bigr = static_cast(param->bigr); fc.c_inner_loop[i][j][k].bigd = static_cast(param->bigd); fc.c_inner_loop[i][j][k].c2 = static_cast(param->c * param->c); fc.c_inner_loop[i][j][k].d2 = static_cast(param->d * param->d); fc.c_inner_loop[i][j][k].h = static_cast(param->h); fc.c_inner_loop[i][j][k].gamma = static_cast(param->gamma); fc.c_inner_loop[i][j][k].powermint = static_cast(param->powermint); fc.c_inner[i][j][k].cutsq = static_cast(param->cutsq); fc.c_inner[i][j][k].lam3 = static_cast(param->lam3); fc.c_inner[i][j][k].bigr = static_cast(param->bigr); fc.c_inner[i][j][k].bigd = static_cast(param->bigd); fc.c_inner[i][j][k].c2 = static_cast(param->c * param->c); fc.c_inner[i][j][k].d2 = static_cast(param->d * param->d); fc.c_inner[i][j][k].h = static_cast(param->h); fc.c_inner[i][j][k].gamma = static_cast(param->gamma); fc.c_inner[i][j][k].powermint = static_cast(param->powermint); } Param * param = ¶ms[elem2param[map[i]][map[j]][map[j]]]; fc.c_cutoff_outer[i][j].cutsq = static_cast(param->cutsq); fc.c_first_loop[i][j].bigr = static_cast(param->bigr); fc.c_first_loop[i][j].bigd = static_cast(param->bigd); fc.c_first_loop[i][j].lam1 = static_cast(param->lam1); fc.c_first_loop[i][j].biga = static_cast(param->biga); fc.c_second_loop[i][j].lam2 = static_cast(param->lam2); fc.c_second_loop[i][j].beta = static_cast(param->beta); fc.c_second_loop[i][j].bigb = static_cast(param->bigb); fc.c_second_loop[i][j].powern = static_cast(param->powern); fc.c_second_loop[i][j].c1 = static_cast(param->c1); fc.c_second_loop[i][j].c2 = static_cast(param->c2); fc.c_second_loop[i][j].c3 = static_cast(param->c3); fc.c_second_loop[i][j].c4 = static_cast(param->c4); fc.c_outer[i][j].cutsq = static_cast(param->cutsq); fc.c_outer[i][j].bigr = static_cast(param->bigr); fc.c_outer[i][j].bigd = static_cast(param->bigd); fc.c_outer[i][j].lam1 = static_cast(param->lam1); fc.c_outer[i][j].biga = static_cast(param->biga); fc.c_outer[i][j].lam2 = static_cast(param->lam2); fc.c_outer[i][j].beta = static_cast(param->beta); fc.c_outer[i][j].bigb = static_cast(param->bigb); fc.c_outer[i][j].powern = static_cast(param->powern); fc.c_outer[i][j].c1 = static_cast(param->c1); fc.c_outer[i][j].c2 = static_cast(param->c2); fc.c_outer[i][j].c3 = static_cast(param->c3); fc.c_outer[i][j].c4 = static_cast(param->c4); } fc.c_outer[i][0].cutsq = 0.; } #ifdef _LMP_INTEL_OFFLOAD if (_cop < 0) return; typename ForceConst::c_first_loop_t * c_first_loop = fc.c_first_loop[0]; typename ForceConst::c_cutoff_t * c_cutoff_outer = fc.c_cutoff_outer[0]; typename ForceConst::c_outer_t * c_outer = fc.c_outer[0]; typename ForceConst::c_second_loop_t * c_second_loop = fc.c_second_loop[0]; typename ForceConst::c_inner_loop_t * c_inner_loop = fc.c_inner_loop[0][0]; typename ForceConst::c_cutoff_t * c_cutoff_inner = fc.c_cutoff_inner[0][0]; typename ForceConst::c_inner_t * c_inner = fc.c_inner[0][0]; flt_t * ocutneighsq = cutneighsq[0]; size_t VL = 512 / 8 / sizeof(flt_t); int ntypes = tp1; int ntypes_pad = ntypes + VL - ntypes % VL; int tp1sq = tp1 * tp1; int tp1cb = tp1 * tp1 * tp1; int tp1cb_pad = tp1 * tp1 * ntypes_pad; #pragma offload_transfer target(mic:_cop) \ in(c_first_loop, c_second_loop, c_cutoff_outer, c_outer : length(tp1sq) alloc_if(0) free_if(0)) \ in(c_inner : length(tp1cb) alloc_if(0) free_if(0)) \ in(c_cutoff_inner : length(tp1cb_pad) alloc_if(0) free_if(0)) \ in(ocutneighsq: length(tp1sq) alloc_if(0) free_if(0)) #endif } /* ---------------------------------------------------------------------- */ // As in any other /intel pair style template void PairTersoffIntel::ForceConst::set_ntypes(const int ntypes, Memory *memory, const int cop) { if ( (ntypes != _ntypes) ) { if (_ntypes > 0) { #ifdef _LMP_INTEL_OFFLOAD c_first_loop_t * oc_first_loop = c_first_loop[0]; c_second_loop_t * oc_second_loop = c_second_loop[0]; c_inner_loop_t * oc_inner_loop = c_inner_loop[0][0]; c_cutoff_t * oc_cutoff_inner = c_cutoff_inner[0][0]; c_cutoff_t * oc_cutoff_outer = c_cutoff_outer[0]; c_inner_t * oc_inner = c_inner[0][0]; c_outer_t * oc_outer = c_outer[0]; if (c_first_loop != NULL && c_second_loop != NULL && c_inner_loop != NULL && _cop >= 0) { #pragma offload_transfer target(mic:cop) \ nocopy(oc_first_loop, oc_second_loop, oc_inner_loop: alloc_if(0) free_if(1)) \ nocopy(oc_cutoff_outer, oc_cutoff_inner: alloc_if(0) free_if(1)) \ nocopy(oc_inner, oc_outer: alloc_if(0) free_if(0)) } #endif _memory->destroy(c_first_loop); _memory->destroy(c_second_loop); _memory->destroy(c_inner_loop); _memory->destroy(c_cutoff_outer); _memory->destroy(c_cutoff_inner); _memory->destroy(c_inner); _memory->destroy(c_outer); } if (ntypes > 0) { _cop = cop; size_t VL = 512 / 8 / sizeof(flt_t); int ntypes_pad = ntypes + VL - ntypes % VL; memory->create(c_first_loop,ntypes,ntypes,"fc.c_first_loop"); memory->create(c_second_loop,ntypes,ntypes,"fc.c_second_loop"); memory->create(c_cutoff_outer,ntypes,ntypes,"fc.c_cutoff_outer"); memory->create(c_inner_loop,ntypes,ntypes,ntypes,"fc.c_inner_loop"); memory->create(c_cutoff_inner,ntypes,ntypes,ntypes_pad,"fc.c_cutoff_inner"); memory->create(c_inner,ntypes,ntypes,ntypes,"fc.c_inner"); memory->create(c_outer,ntypes,ntypes,"fc.c_outer"); #ifdef _LMP_INTEL_OFFLOAD c_first_loop_t * oc_first_loop = c_first_loop[0]; c_second_loop_t * oc_second_loop = c_second_loop[0]; c_cutoff_t * oc_cutoff_outer = c_cutoff_outer[0]; c_inner_loop_t * oc_inner_loop = c_inner_loop[0][0]; c_cutoff_t * oc_cutoff_inner = c_cutoff_inner[0][0]; c_inner_t * oc_inner = c_inner[0][0]; c_outer_t * oc_outer = c_outer[0]; int tp1sq = ntypes * ntypes; int tp1cb = ntypes * ntypes * ntypes; int tp1cb_pad = ntypes * ntypes * ntypes_pad; if (oc_first_loop != NULL && oc_second_loop != NULL && oc_inner_loop != NULL && cop >= 0) { #pragma offload_transfer target(mic:cop) \ nocopy(oc_first_loop: length(tp1sq) alloc_if(1) free_if(0)) \ nocopy(oc_second_loop: length(tp1sq) alloc_if(1) free_if(0)) \ nocopy(oc_cutoff_outer: length(tp1sq) alloc_if(1) free_if(0)) \ nocopy(oc_outer: length(tp1sq) alloc_if(1) free_if(0)) \ nocopy(oc_inner_loop: length(tp1cb) alloc_if(1) free_if(0)) \ nocopy(oc_inner: length(tp1cb) alloc_if(1) free_if(0)) \ nocopy(oc_cutoff_inner: length(tp1cb_pad) alloc_if(1) free_if(0)) } #endif } } _ntypes=ntypes; _memory=memory; } #ifdef _LMP_INTEL_OFFLOAD #pragma offload_attribute(push,target(mic)) #endif // The factor up to which we do caching static const int N_CACHE = 8; template template void IntelKernelTersoff::kernel_step( int eatom, int vflag, const int * _noalias const numneigh, const int * _noalias const cnumneigh, const int * _noalias const firstneigh, int ntypes, typename IntelBuffers::atom_t * _noalias const x, const typename PairTersoffIntel::ForceConst::c_inner_t * _noalias const c_inner, const typename PairTersoffIntel::ForceConst::c_outer_t * _noalias const c_outer, typename IntelBuffers::vec3_acc_t * _noalias const f, avec *vsevdwl, avec *vsv0, avec *vsv1, avec *vsv2, avec* vsv3, avec *vsv4, avec *vsv5, int compress_idx, iarr is, iarr js, bvec vmask_repulsive ) { ivec v_i4floats((int) (4 * sizeof(typename v::fscal))); ivec v_i1(1); fvec v_2(0.); fvec v_0_5(0.5); ivec v_i0(0); ivec v_i_ntypes(ntypes); ivec v_i_NEIGHMASK(NEIGHMASK); farr fx, fy, fz, fw; int cache_idx = 0; fvec vfkx_cache[N_CACHE]; fvec vfky_cache[N_CACHE]; fvec vfkz_cache[N_CACHE]; ivec vks_cache[N_CACHE]; bvec vmask_cache[N_CACHE]; ivec vkks_final_cache; bvec vmask_final_cache; iarr ts; // compute all the stuff we know from i and j // TDO: We could extract this from the driver routine ivec vis = v::int_mullo(v_i4floats, v::int_load_vl(is)); ivec vjs = v::int_mullo(v_i4floats, v::int_load_vl(js)); bvec vmask = v::mask_enable_lower(compress_idx); fvec vx_i = v::zero(), vy_i = v::zero(), vz_i = v::zero(); ivec vw_i = v_i0; v::gather_x(vis, vmask, x, &vx_i, &vy_i, &vz_i, &vw_i); fvec vx_j = v::zero(), vy_j = v::zero(), vz_j = v::zero(); ivec vw_j = v_i0; v::gather_x(vjs, vmask, x, &vx_j, &vy_j, &vz_j, &vw_j); fvec vdx_ij = vx_j - vx_i, vdy_ij = vy_j - vy_i, vdz_ij = vz_j - vz_i; fvec vrijsq = vdx_ij * vdx_ij + vdy_ij * vdy_ij + vdz_ij * vdz_ij; fvec vrij = sqrt(vrijsq); ivec vis_orig = v::int_load_vl(is); ivec vcnumneigh_i = v::int_gather<4>(v_i0, vmask, vis_orig, cnumneigh); ivec vnumneigh_i = v::int_gather<4>(v_i0, vmask, vis_orig, numneigh); ivec vc_idx_ij = v::int_mullo(v_i4floats, vw_j + v::int_mullo(v_i_ntypes, vw_i)); fvec vzeta = v::zero(); fvec vfxtmp = v::zero(), vfytmp = v::zero(), vfztmp = v::zero(); fvec vfjxtmp = v::zero(), vfjytmp = v::zero(), vfjztmp = v::zero(); // This piece of code faciliates the traversal of the k loop assuming // nothing about i. As such, it uses masking to avoid superfluous loads // and fast-forwards each lane until work is available. // This is useful because we can not make assumptions as to where in the // neighbor list the atoms within the cutoff might be. // We also implement the caching in here, i.e. collect force contributions // due to zeta. // This means that you will see four loops: // 1. the loop that does zeta calculation and caches the force contributions // 2. the loop that processes the remaining zeta calculations // 3. the loop that updates the force based on the cached force contributions // 4. the loop that computes force contributions for the remainder { ivec vkks = v_i0; bvec vactive_mask = vmask; bvec veff_old_mask(0); ivec vks, vw_k; fvec vx_k, vy_k, vz_k, vcutsq; while (! v::mask_testz(vactive_mask) && cache_idx < N_CACHE) { bvec vnew_mask = vactive_mask & ~ veff_old_mask; vks = v::int_mullo(v_i4floats, v_i_NEIGHMASK & v::int_gather<4>(vks, vactive_mask, vkks + vcnumneigh_i, firstneigh)); v::gather_x(vks, vnew_mask, x, &vx_k, &vy_k, &vz_k, &vw_k); fvec vdx_ik = (vx_k - vx_i); fvec vdy_ik = (vy_k - vy_i); fvec vdz_ik = (vz_k - vz_i); fvec vrsq = vdx_ik * vdx_ik + vdy_ik * vdy_ik + vdz_ik * vdz_ik; ivec vc_idx = v::int_mullo(v_i4floats, vw_k) + v::int_mullo(v_i_ntypes, vc_idx_ij); vcutsq = v::gather<4>(vcutsq, vnew_mask, vc_idx, c_inner); bvec vcutoff_mask = v::cmplt(vrsq, vcutsq); bvec vsame_mask = v::int_cmpneq(vjs, vks); bvec veff_mask = vcutoff_mask & vsame_mask & vactive_mask; if (v::mask_testz(~(veff_mask | ~vactive_mask))) { fvec vzeta_contrib; fvec vfix, vfiy, vfiz; fvec vfjx, vfjy, vfjz; fvec vfkx, vfky, vfkz; attractive_vector(c_inner,vc_idx,veff_mask,fvec(1.), vrij,vrsq,vdx_ij,vdy_ij,vdz_ij,vdx_ik,vdy_ik,vdz_ik, &vfix,&vfiy,&vfiz, &vfjx,&vfjy,&vfjz, &vfkx,&vfky,&vfkz, &vzeta_contrib); vfxtmp = v::mask_add(vfxtmp, veff_mask, vfxtmp, vfix); vfytmp = v::mask_add(vfytmp, veff_mask, vfytmp, vfiy); vfztmp = v::mask_add(vfztmp, veff_mask, vfztmp, vfiz); vfjxtmp = v::mask_add(vfjxtmp, veff_mask, vfjxtmp, vfjx); vfjytmp = v::mask_add(vfjytmp, veff_mask, vfjytmp, vfjy); vfjztmp = v::mask_add(vfjztmp, veff_mask, vfjztmp, vfjz); vfkx_cache[cache_idx] = vfkx; vfky_cache[cache_idx] = vfky; vfkz_cache[cache_idx] = vfkz; vks_cache[cache_idx] = vks; vmask_cache[cache_idx] = veff_mask; cache_idx += 1; vzeta = v::mask_add(vzeta, veff_mask, vzeta, vzeta_contrib); vkks = vkks + v_i1; veff_old_mask = bvec(0); } else { vkks = v::int_mask_add(vkks, ~veff_mask, vkks, v_i1); veff_old_mask = veff_mask; } vactive_mask &= v::int_cmplt(vkks, vnumneigh_i); } vkks_final_cache = vkks; vmask_final_cache = vactive_mask; while (! v::mask_testz(vactive_mask)) { bvec vnew_mask = vactive_mask & ~ veff_old_mask; vks = v::int_mullo(v_i4floats, v_i_NEIGHMASK & v::int_gather<4>(vks, vactive_mask, vkks + vcnumneigh_i, firstneigh)); v::gather_x(vks, vnew_mask, x, &vx_k, &vy_k, &vz_k, &vw_k); fvec vdx_ik = (vx_k - vx_i); fvec vdy_ik = (vy_k - vy_i); fvec vdz_ik = (vz_k - vz_i); fvec vrsq = vdx_ik * vdx_ik + vdy_ik * vdy_ik + vdz_ik * vdz_ik; ivec vc_idx = v::int_mullo(v_i4floats, vw_k) + v::int_mullo(v_i_ntypes, vc_idx_ij); vcutsq = v::gather<4>(vcutsq, vnew_mask, vc_idx, c_inner); bvec vcutoff_mask = v::cmplt(vrsq, vcutsq); bvec vsame_mask = v::int_cmpneq(vjs, vks); bvec veff_mask = vcutoff_mask & vsame_mask & vactive_mask; if (v::mask_testz(~(veff_mask | ~vactive_mask))) { fvec vzeta_contrib; vzeta_contrib = zeta_vector(c_inner,vc_idx,veff_mask,vrij,vrsq,vdx_ij,vdy_ij,vdz_ij,vdx_ik,vdy_ik,vdz_ik); vzeta = v::mask_add(vzeta, veff_mask, vzeta, vzeta_contrib); vkks = vkks + v_i1; veff_old_mask = bvec(0); } else { vkks = v::int_mask_add(vkks, ~veff_mask, vkks, v_i1); veff_old_mask = veff_mask; } vactive_mask &= v::int_cmplt(vkks, vnumneigh_i); } } fvec vfpair, vevdwl, vprefactor, vfwtmp, vfjwtmp; force_zeta_vector(c_outer, vc_idx_ij, vmask, vrij, vzeta, &vfpair, &vprefactor, EFLAG, &vevdwl, vmask_repulsive); vfxtmp = vfxtmp * vprefactor + vdx_ij * vfpair; vfytmp = vfytmp * vprefactor + vdy_ij * vfpair; vfztmp = vfztmp * vprefactor + vdz_ij * vfpair; vfjxtmp = vfjxtmp * vprefactor - vdx_ij * vfpair; vfjytmp = vfjytmp * vprefactor - vdy_ij * vfpair; vfjztmp = vfjztmp * vprefactor - vdz_ij * vfpair; if (EVFLAG) { if (EFLAG) { *vsevdwl = v::acc_mask_add(*vsevdwl, vmask, *vsevdwl, vevdwl); if (eatom) { v::store(fw, (v_0_5 * vevdwl)); } } if (vflag == 1) { *vsv0 = v::acc_mask_add(*vsv0, vmask, *vsv0, vdx_ij * vdx_ij * vfpair); *vsv1 = v::acc_mask_add(*vsv1, vmask, *vsv1, vdy_ij * vdy_ij * vfpair); *vsv2 = v::acc_mask_add(*vsv2, vmask, *vsv2, vdz_ij * vdz_ij * vfpair); *vsv3 = v::acc_mask_add(*vsv3, vmask, *vsv3, vdx_ij * vdy_ij * vfpair); *vsv4 = v::acc_mask_add(*vsv4, vmask, *vsv4, vdx_ij * vdz_ij * vfpair); *vsv5 = v::acc_mask_add(*vsv5, vmask, *vsv5, vdy_ij * vdz_ij * vfpair); } } { while (cache_idx-- > 0) { fvec vfkx = vprefactor * vfkx_cache[cache_idx]; fvec vfky = vprefactor * vfky_cache[cache_idx]; fvec vfkz = vprefactor * vfkz_cache[cache_idx]; ivec vks = vks_cache[cache_idx]; bvec veff_mask = vmask_cache[cache_idx]; v::store(fx, vfkx); v::store(fy, vfky); v::store(fz, vfkz); v::int_store(ts, vks); for (int t = 0; t < v::VL; t++) { if (v::mask_test_at(veff_mask, t)) { int t_ = ts[t] / (4 * sizeof(typename v::fscal)); f[t_].x += fx[t]; f[t_].y += fy[t]; f[t_].z += fz[t]; } } } ivec vkks = vkks_final_cache; bvec vactive_mask = vmask_final_cache; bvec veff_old_mask(0); ivec vks, vw_k; fvec vx_k, vy_k, vz_k, vcutsq; while (! v::mask_testz(vactive_mask)) { bvec vnew_mask = vactive_mask & ~ veff_old_mask; vks = v::int_mullo(v_i4floats, v_i_NEIGHMASK & v::int_gather<4>(vks, vactive_mask, vkks + vcnumneigh_i, firstneigh)); v::gather_x(vks, vnew_mask, x, &vx_k, &vy_k, &vz_k, &vw_k); fvec vdx_ik = vx_k - vx_i; fvec vdy_ik = vy_k - vy_i; fvec vdz_ik = vz_k - vz_i; fvec vrsq = vdx_ik * vdx_ik + vdy_ik * vdy_ik + vdz_ik * vdz_ik; ivec vc_idx = v::int_mullo(v_i4floats, vw_k) + v::int_mullo(v_i_ntypes, vc_idx_ij); vcutsq = v::gather<4>(vcutsq, vnew_mask, vc_idx, c_inner); bvec vcutoff_mask = v::cmplt(vrsq, vcutsq); bvec vsame_mask = v::int_cmpneq(vjs, vks); bvec veff_mask = vcutoff_mask & vsame_mask & vactive_mask; if (v::mask_testz(~(veff_mask | ~vactive_mask))) { fvec vfix, vfiy, vfiz; fvec vfjx, vfjy, vfjz; fvec vfkx, vfky, vfkz; attractive_vector(c_inner,vc_idx,veff_mask,vprefactor, vrij,vrsq,vdx_ij,vdy_ij,vdz_ij,vdx_ik,vdy_ik,vdz_ik, &vfix,&vfiy,&vfiz, &vfjx,&vfjy,&vfjz, &vfkx,&vfky,&vfkz, 0); vfxtmp = v::mask_add(vfxtmp, veff_mask, vfxtmp, vfix); vfytmp = v::mask_add(vfytmp, veff_mask, vfytmp, vfiy); vfztmp = v::mask_add(vfztmp, veff_mask, vfztmp, vfiz); vfjxtmp = v::mask_add(vfjxtmp, veff_mask, vfjxtmp, vfjx); vfjytmp = v::mask_add(vfjytmp, veff_mask, vfjytmp, vfjy); vfjztmp = v::mask_add(vfjztmp, veff_mask, vfjztmp, vfjz); v::store(fx, vfkx); v::store(fy, vfky); v::store(fz, vfkz); v::int_store(ts, vks); for (int t = 0; t < v::VL; t++) { if (v::mask_test_at(veff_mask, t)) { int t_ = ts[t] / (4 * sizeof(typename v::fscal)); f[t_].x += fx[t]; f[t_].y += fy[t]; f[t_].z += fz[t]; } } vkks = vkks + v_i1; veff_old_mask = bvec(0); } else { vkks = v::int_mask_add(vkks, ~veff_mask, vkks, v_i1); veff_old_mask = veff_mask; } vactive_mask &= v::int_cmplt(vkks, vnumneigh_i); } // while (vactive_mask != 0) } // section k // We can not make any assumptions regarding conflicts. // So we sequentialize this. // TDO: Once AVX-512 is around check out VPCONFLICT v::store(fx, vfjxtmp); v::store(fy, vfjytmp); v::store(fz, vfjztmp); for (int t = 0; t < compress_idx; t++) { int t_ = js[t]; f[t_].x += fx[t]; f[t_].y += fy[t]; f[t_].z += fz[t]; if (EVFLAG && EFLAG && eatom) { f[t_].w += fw[t]; } } v::store(fx, vfxtmp); v::store(fy, vfytmp); v::store(fz, vfztmp); for (int t = 0; t < compress_idx; t++) { int t_ = is[t]; f[t_].x += fx[t]; f[t_].y += fy[t]; f[t_].z += fz[t]; if (EVFLAG && EFLAG && eatom) { f[t_].w += fw[t]; } } } // Specialized kernel step for fixed i, means that we don't have to use the // convoluted iteration scheme above, as the loop variables are uniform. template template void IntelKernelTersoff::kernel_step_const_i( int eatom, int vflag, const int * _noalias const numneigh, const int * _noalias const cnumneigh, const int * _noalias const firstneigh, int ntypes, typename IntelBuffers::atom_t * _noalias const x, const typename PairTersoffIntel::ForceConst::c_inner_t * _noalias const c_inner, const typename PairTersoffIntel::ForceConst::c_outer_t * _noalias const c_outer, typename IntelBuffers::vec3_acc_t * _noalias const f, avec *vsevdwl, avec *vsv0, avec *vsv1, avec *vsv2, avec* vsv3, avec *vsv4, avec *vsv5, int compress_idx, int i, iarr js, bvec vmask_repulsive ) { typedef typename v::fvec fvec; typedef typename v::ivec ivec; typedef typename v::bvec bvec; typedef typename v::farr farr; typedef typename v::iarr iarr; typedef typename v::avec avec; typedef typename v::aarr aarr; ivec v_i4floats((int) (4 * sizeof(typename v::fscal))); ivec v_i1(1), v_i0(0), v_i_ntypes(ntypes), v_i_NEIGHMASK(NEIGHMASK); fvec v_0_5(0.5); int cache_idx = 0; fvec vfkx_cache[N_CACHE]; fvec vfky_cache[N_CACHE]; fvec vfkz_cache[N_CACHE]; int k_cache[N_CACHE]; bvec vmask_cache[N_CACHE]; int kk_final_cache; aarr fx, fy, fz, fw; iarr ts; bvec vmask = v::mask_enable_lower(compress_idx); fvec vx_i(x[i].x), vy_i(x[i].y), vz_i(x[i].z); int w_i = x[i].w; ivec vjs = v::int_mullo(v_i4floats, v::int_load_vl(js)); fvec vx_j = v::zero(), vy_j = v::zero(), vz_j = v::zero(); ivec vw_j = v_i0; v::gather_x(vjs, vmask, x, &vx_j, &vy_j, &vz_j, &vw_j); fvec vdx_ij = vx_j - vx_i, vdy_ij = vy_j - vy_i, vdz_ij = vz_j - vz_i; fvec vrijsq = vdx_ij * vdx_ij + vdy_ij * vdy_ij + vdz_ij * vdz_ij; fvec vrij = sqrt(vrijsq); int cnumneigh_i = cnumneigh[i]; int numneigh_i = numneigh[i]; ivec vc_idx_j = v::int_mullo(v_i4floats, vw_j); ivec vc_idx_j_ntypes = v::int_mullo(v_i_ntypes, vc_idx_j); avec vzeta = v::acc_zero(); avec vfxtmp = v::acc_zero(), vfytmp = v::acc_zero(), vfztmp = v::acc_zero(); avec vfjxtmp = v::acc_zero(), vfjytmp = v::acc_zero(), vfjztmp = v::acc_zero(); // Same structure as kernel_step, just simpler as the loops all iterate over // the same k int kk = 0; for (; kk < numneigh_i && cache_idx < N_CACHE; kk++) { int k = firstneigh[kk + cnumneigh_i] & NEIGHMASK; fvec vx_k(x[k].x); fvec vy_k(x[k].y); fvec vz_k(x[k].z); int w_k = x[k].w; fvec vdx_ik = vx_k - vx_i; fvec vdy_ik = vy_k - vy_i; fvec vdz_ik = vz_k - vz_i; fvec vrsq = vdx_ik * vdx_ik + vdy_ik * vdy_ik + vdz_ik * vdz_ik; fvec vcutsq = v::gather<4>(v::zero(), vmask, vc_idx_j_ntypes, &c_inner[ntypes * ntypes * w_i + w_k]); bvec vcutoff_mask = v::cmplt(vrsq, vcutsq); bvec vsame_mask = v::int_cmpneq(vjs, ivec(static_cast(4 * sizeof(typename v::fscal) * k))); bvec veff_mask = vcutoff_mask & vsame_mask & vmask; if (! v::mask_testz(veff_mask)) { fvec vzeta_contrib; fvec vfix, vfiy, vfiz; fvec vfjx, vfjy, vfjz; fvec vfkx, vfky, vfkz; attractive_vector(&c_inner[ntypes * ntypes * w_i + w_k],vc_idx_j_ntypes,veff_mask,fvec(1.), vrij,vrsq,vdx_ij,vdy_ij,vdz_ij,vdx_ik,vdy_ik,vdz_ik, &vfix,&vfiy,&vfiz, &vfjx,&vfjy,&vfjz, &vfkx,&vfky,&vfkz, &vzeta_contrib); vfxtmp = v::acc_mask_add(vfxtmp, veff_mask, vfxtmp, vfix); vfytmp = v::acc_mask_add(vfytmp, veff_mask, vfytmp, vfiy); vfztmp = v::acc_mask_add(vfztmp, veff_mask, vfztmp, vfiz); vfjxtmp = v::acc_mask_add(vfjxtmp, veff_mask, vfjxtmp, vfjx); vfjytmp = v::acc_mask_add(vfjytmp, veff_mask, vfjytmp, vfjy); vfjztmp = v::acc_mask_add(vfjztmp, veff_mask, vfjztmp, vfjz); vfkx_cache[cache_idx] = v::mask_add(v::zero(), veff_mask, vfkx, v::zero()); vfky_cache[cache_idx] = v::mask_add(v::zero(), veff_mask, vfky, v::zero()); vfkz_cache[cache_idx] = v::mask_add(v::zero(), veff_mask, vfkz, v::zero()); vmask_cache[cache_idx] = veff_mask; k_cache[cache_idx] = k; cache_idx += 1; vzeta = v::acc_mask_add(vzeta, veff_mask, vzeta, vzeta_contrib); } } kk_final_cache = kk; for (; kk < numneigh_i; kk++) { int k = firstneigh[kk + cnumneigh_i] & NEIGHMASK; fvec vx_k(x[k].x); fvec vy_k(x[k].y); fvec vz_k(x[k].z); int w_k = x[k].w; fvec vdx_ik = vx_k - vx_i; fvec vdy_ik = vy_k - vy_i; fvec vdz_ik = vz_k - vz_i; fvec vrsq = vdx_ik * vdx_ik + vdy_ik * vdy_ik + vdz_ik * vdz_ik; fvec vcutsq = v::gather<4>(v::zero(), vmask, vc_idx_j_ntypes, &c_inner[ntypes * ntypes * w_i + w_k]); bvec vcutoff_mask = v::cmplt(vrsq, vcutsq); bvec vsame_mask = v::int_cmpneq(vjs, ivec(static_cast(4 * sizeof(typename v::fscal) * k))); bvec veff_mask = vcutoff_mask & vsame_mask & vmask; if (! v::mask_testz(veff_mask)) { fvec vzeta_contrib = zeta_vector(&c_inner[ntypes * ntypes * w_i + w_k], vc_idx_j_ntypes, veff_mask, vrij, vrsq, vdx_ij,vdy_ij,vdz_ij,vdx_ik,vdy_ik,vdz_ik); vzeta = v::acc_mask_add(vzeta, veff_mask, vzeta, vzeta_contrib); } } fvec vfpair, vevdwl, vprefactor, vfwtmp; force_zeta_vector(&c_outer[ntypes * w_i], vc_idx_j, vmask, vrij, vzeta, &vfpair, &vprefactor, EFLAG, &vevdwl, vmask_repulsive); avec vaprefactor(vprefactor); vfxtmp = vfxtmp * vaprefactor + avec(vdx_ij * vfpair); vfytmp = vfytmp * vaprefactor + avec(vdy_ij * vfpair); vfztmp = vfztmp * vaprefactor + avec(vdz_ij * vfpair); vfjxtmp = vfjxtmp * vaprefactor - avec(vdx_ij * vfpair); vfjytmp = vfjytmp * vaprefactor - avec(vdy_ij * vfpair); vfjztmp = vfjztmp * vaprefactor - avec(vdz_ij * vfpair); if (EVFLAG) { if (EFLAG) { *vsevdwl = v::acc_mask_add(*vsevdwl, vmask, *vsevdwl, vevdwl); if (eatom) { vfwtmp = v_0_5 * vevdwl; v::store(fw, vfwtmp); } } if (vflag == 1) { *vsv0 = v::acc_mask_add(*vsv0, vmask, *vsv0, vdx_ij * vdx_ij * vfpair); *vsv1 = v::acc_mask_add(*vsv1, vmask, *vsv1, vdy_ij * vdy_ij * vfpair); *vsv2 = v::acc_mask_add(*vsv2, vmask, *vsv2, vdz_ij * vdz_ij * vfpair); *vsv3 = v::acc_mask_add(*vsv3, vmask, *vsv3, vdx_ij * vdy_ij * vfpair); *vsv4 = v::acc_mask_add(*vsv4, vmask, *vsv4, vdx_ij * vdz_ij * vfpair); *vsv5 = v::acc_mask_add(*vsv5, vmask, *vsv5, vdy_ij * vdz_ij * vfpair); } } while (cache_idx-- > 0) { fvec vfkx = vprefactor * vfkx_cache[cache_idx]; fvec vfky = vprefactor * vfky_cache[cache_idx]; fvec vfkz = vprefactor * vfkz_cache[cache_idx]; int k = k_cache[cache_idx]; bvec veff_mask = vmask_cache[cache_idx]; f[k].x += v::reduce_add(v::mask_add(v::zero(), veff_mask, vfkx, v::zero())); f[k].y += v::reduce_add(v::mask_add(v::zero(), veff_mask, vfky, v::zero())); f[k].z += v::reduce_add(v::mask_add(v::zero(), veff_mask, vfkz, v::zero())); } for (int kk = kk_final_cache; kk < numneigh_i; kk++) { int k = firstneigh[kk + cnumneigh_i] & NEIGHMASK; fvec vx_k(x[k].x); fvec vy_k(x[k].y); fvec vz_k(x[k].z); int w_k = x[k].w; fvec vdx_ik = vx_k - vx_i; fvec vdy_ik = vy_k - vy_i; fvec vdz_ik = vz_k - vz_i; fvec vrsq = vdx_ik * vdx_ik + vdy_ik * vdy_ik + vdz_ik * vdz_ik; fvec vcutsq = v::gather<4>(v::zero(), vmask, vc_idx_j_ntypes, &c_inner[ntypes * ntypes * w_i + w_k].cutsq); bvec vcutoff_mask = v::cmplt(vrsq, vcutsq); bvec vsame_mask = v::int_cmpneq(vjs, ivec(static_cast(4 * sizeof(typename v::fscal) * k))); bvec veff_mask = vcutoff_mask & vsame_mask & vmask; if (! v::mask_testz(veff_mask)) { fvec vfix, vfiy, vfiz; fvec vfjx, vfjy, vfjz; fvec vfkx, vfky, vfkz; attractive_vector(&c_inner[ntypes * ntypes * w_i + w_k],vc_idx_j_ntypes,veff_mask,vprefactor, vrij,vrsq,vdx_ij,vdy_ij,vdz_ij,vdx_ik,vdy_ik,vdz_ik, &vfix,&vfiy,&vfiz, &vfjx,&vfjy,&vfjz, &vfkx,&vfky,&vfkz, 0); vfxtmp = v::acc_mask_add(vfxtmp, veff_mask, vfxtmp, vfix); vfytmp = v::acc_mask_add(vfytmp, veff_mask, vfytmp, vfiy); vfztmp = v::acc_mask_add(vfztmp, veff_mask, vfztmp, vfiz); vfjxtmp = v::acc_mask_add(vfjxtmp, veff_mask, vfjxtmp, vfjx); vfjytmp = v::acc_mask_add(vfjytmp, veff_mask, vfjytmp, vfjy); vfjztmp = v::acc_mask_add(vfjztmp, veff_mask, vfjztmp, vfjz); f[k].x += v::reduce_add(v::mask_add(v::zero(), veff_mask, vfkx, v::zero())); f[k].y += v::reduce_add(v::mask_add(v::zero(), veff_mask, vfky, v::zero())); f[k].z += v::reduce_add(v::mask_add(v::zero(), veff_mask, vfkz, v::zero())); } } // TDO: This could be a scatter v::acc_store(fx, vfjxtmp); v::acc_store(fy, vfjytmp); v::acc_store(fz, vfjztmp); for (int t = 0; t < compress_idx; t++) { int t_ = js[t]; f[t_].x += fx[t]; f[t_].y += fy[t]; f[t_].z += fz[t]; if (EVFLAG && EFLAG && eatom) { f[t_].w += fw[t]; } } f[i].x += v::acc_reduce_add(v::acc_mask_add(v::acc_zero(), vmask, vfxtmp, v::zero())); f[i].y += v::acc_reduce_add(v::acc_mask_add(v::acc_zero(), vmask, vfytmp, v::zero())); f[i].z += v::acc_reduce_add(v::acc_mask_add(v::acc_zero(), vmask, vfztmp, v::zero())); if (EVFLAG && EFLAG && eatom) { f[i].z += v::acc_reduce_add(v::acc_mask_add(v::acc_zero(), vmask, vfwtmp, v::zero())); } } template template void IntelKernelTersoff::kernel( int iito, int iifrom, int eatom, int vflag, const int * _noalias const numneigh, const int * _noalias const numneighhalf, const int * _noalias const cnumneigh, const int * _noalias const firstneigh, int ntypes, typename IntelBuffers::atom_t * _noalias const x, const c_inner_t * _noalias const c_inner, const c_outer_t * _noalias const c_outer, typename IntelBuffers::vec3_acc_t * _noalias const f, acc_t *evdwl, acc_t *ov0, acc_t * ov1, acc_t *ov2, acc_t* ov3, acc_t *ov4, acc_t *ov5 ) { int compress_idx = 0; int ii, jj; iarr is, js; avec vsevdwl = v::acc_zero(); avec vsv0 = v::acc_zero(), vsv1 = v::acc_zero(), vsv2 = v::acc_zero(); avec vsv3 = v::acc_zero(), vsv4 = v::acc_zero(), vsv5 = v::acc_zero(); ivec v_i4floats(static_cast(sizeof(typename v::fscal) * 4)); ivec vj, v_NEIGHMASK(NEIGHMASK); bvec vmask_repulsive(0); iarr repulsive_flag = {0}; // If you want to get the very most out of this, please uncomment. // Consider getting a coffee or doing something else. // Also good for heating. //#pragma forceinline recursive for (ii = iifrom; ii < iito; ii++) { // Right now this loop is scalar, to allow for the compiler to do // its prefetching magic. int i = ii; int w_i = x[i].w; flt_t x_i = x[i].x; flt_t y_i = x[i].y; flt_t z_i = x[i].z; int jlist_off_i = cnumneigh[i]; int jnum = numneigh[ii]; for (jj = 0; jj < jnum; jj++) { int j = firstneigh[jlist_off_i + jj] & NEIGHMASK; int w_j = x[j].w; flt_t dx_ij = x[j].x - x_i; flt_t dy_ij = x[j].y - y_i; flt_t dz_ij = x[j].z - z_i; flt_t rsq = dx_ij*dx_ij + dy_ij*dy_ij + dz_ij*dz_ij; flt_t cutsq = c_outer[w_i * ntypes + w_j].cutsq; if (rsq < cutsq) { is[compress_idx] = ii; js[compress_idx] = j; if (jj < numneighhalf[i]) repulsive_flag[compress_idx] = 1; compress_idx += 1; } if (pack_i) { if (compress_idx == v::VL) { vmask_repulsive = v::int_cmpneq(v::int_load_vl(repulsive_flag), ivec(0)); kernel_step( eatom, vflag, numneigh, cnumneigh, firstneigh, ntypes, x, c_inner, c_outer, f, &vsevdwl, &vsv0, &vsv1, &vsv2, &vsv3, &vsv4, &vsv5, compress_idx, is, js, vmask_repulsive ); compress_idx = 0; v::int_clear_arr(repulsive_flag); } } else { if (compress_idx == v::VL || (compress_idx > 0 && jj == jnum-1)) { vmask_repulsive = v::int_cmpneq(v::int_load_vl(repulsive_flag), ivec(0)); kernel_step_const_i( eatom, vflag, numneigh, cnumneigh, firstneigh, ntypes, x, c_inner, c_outer, f, &vsevdwl, &vsv0, &vsv1, &vsv2, &vsv3, &vsv4, &vsv5, compress_idx, i, js, vmask_repulsive ); compress_idx = 0; v::int_clear_arr(repulsive_flag); } } } } if (compress_idx > 0) { vmask_repulsive = v::int_cmpneq(v::int_load_vl(repulsive_flag), ivec(0)); IntelKernelTersoff::kernel_step( eatom, vflag, numneigh, cnumneigh, firstneigh, ntypes, x, c_inner, c_outer, f, &vsevdwl, &vsv0, &vsv1, &vsv2, &vsv3, &vsv4, &vsv5, compress_idx, is, js, vmask_repulsive ); } if (EVFLAG) { if (EFLAG) { *evdwl += v::acc_reduce_add(vsevdwl); } if (vflag == 1) { *ov0 += v::acc_reduce_add(vsv0); *ov1 += v::acc_reduce_add(vsv1); *ov2 += v::acc_reduce_add(vsv2); *ov3 += v::acc_reduce_add(vsv3); *ov4 += v::acc_reduce_add(vsv4); *ov5 += v::acc_reduce_add(vsv5); } } } template IntelKernelTersoff::fvec IntelKernelTersoff::zeta_vector( const c_inner_t * param, ivec xjw, bvec mask, fvec vrij, fvec rsq2, fvec vdijx, fvec vdijy, fvec vdijz, fvec dikx, fvec diky, fvec dikz ) { fvec v_1_0(1.0); fvec v_0_5(0.5); fvec vph = v::zero(), vpc2 = v::zero(), vpd2 = v::zero(), vpgamma = v::zero(), vplam3 = v::zero(), vppowermint = v::zero(), vpbigr = v::zero(), vpbigd = v::zero(); // TDO: Specialize on number of species v::gather_8(xjw, mask, ¶m[0].lam3, &vplam3, &vppowermint, &vpbigr, &vpbigd, &vpc2, &vpd2, &vph, &vpgamma); fvec vrik = sqrt(rsq2); fvec vcostheta = (vdijx * dikx + vdijy * diky + vdijz * dikz) * v::recip(vrij * vrik); fvec vhcth = vph - vcostheta; fvec vgijk_a = vhcth * vhcth; fvec vgijk = vpgamma * (v_1_0 + vpc2 * vgijk_a * v::recip(vpd2 * (vpd2 + vgijk_a))); fvec varg1 = vplam3 * (vrij - vrik); fvec varg3 = varg1 * varg1 * varg1; bvec mask_ex = v::cmpeq(vppowermint, fvec(3.)); fvec varg = v::blend(mask_ex, varg1, varg3); fvec vex_delr = v::min(fvec(1.e30), exp(varg)); bvec vmask_need_sine = v::cmpnle(vrik, vpbigr - vpbigd) & mask; fvec vfc = v_1_0; // Its kind of important to check the mask. // Some simulations never/rarely invoke this branch. if (! v::mask_testz(vmask_need_sine)) { vfc = v::blend(vmask_need_sine, vfc, v_0_5 * (v_1_0 - sin(fvec(MY_PI2) * (vrik - vpbigr) * v::recip(vpbigd)))); } return vgijk * vex_delr * vfc; } template void IntelKernelTersoff::force_zeta_vector( const c_outer_t * param, ivec xjw, bvec mask, fvec vrij, fvec vzeta_ij, fvec *vfpair, fvec *vprefactor, int EVDWL, fvec *vevdwl, bvec vmask_repulsive ) { fvec v_0_0(0.0); fvec v_0_5(0.5); fvec v_m0_5(-0.5); fvec v_1_0(1.0); fvec v_m1_0(-1.0); fvec v_2_0(2.0); fvec vpbigr = v::zero(), vpbigd = v::zero(), vplam1 = v::zero(), vpbiga = v::zero(), vplam2 = v::zero(), vpbeta = v::zero(), vpbigb = v::zero(), vppowern = v::zero(); v::gather_8(xjw, mask, ¶m[0].bigr, &vpbigr, &vpbigd, &vplam1, &vpbiga, &vplam2, &vpbeta, &vpbigb, &vppowern); fvec vfccos; // This is pretty much a literal translation. bvec vmask_need_sine = v::cmpnle(vrij, vpbigr - vpbigd) & mask; fvec vfc = v_1_0; fvec vfc_d = v_0_0; if (! v::mask_testz(vmask_need_sine)) { fvec vtmp = fvec(MY_PI2) * v::recip(vpbigd); vfc = v::blend(vmask_need_sine, vfc, v_0_5 * (v_1_0 - v::sincos(&vfccos, vtmp * (vrij - vpbigr)))); vfc_d = v::blend(vmask_need_sine, vfc_d, v_m0_5 * vtmp * vfccos); } fvec vpminus_lam2 = - vplam2; fvec vpminus_bigb = -vpbigb; fvec vexp = exp(vpminus_lam2 * vrij); fvec vfa = vpminus_bigb * vexp * vfc; fvec vfa_d = vpminus_lam2 * vfa + vpminus_bigb * vexp * vfc_d; fvec vpc1 = v::zero(), vpc2 = v::zero(), vpc3 = v::zero(), vpc4 = v::zero(); v::gather_4(xjw, mask, ¶m[0].c1, &vpc1, &vpc2, &vpc3, &vpc4); fvec vpminus_powern = - vppowern; fvec vbij(0.), vbij_d(0.); fvec vtmp = vpbeta * vzeta_ij; bvec vmc1 = v::cmple(vpc1, vtmp) & mask; if (! v::mask_testz(vmc1)) { vbij = v::invsqrt(vtmp); vbij_d = vpbeta * v_m0_5 * vbij * v::recip(vtmp); } bvec vmc2 = v::cmple(vpc2, vtmp) & ~ vmc1 & mask; if (! v::mask_testz(vmc2)) { fvec vpowminus_powern = pow(vtmp, vpminus_powern); fvec vinvsqrt = v::invsqrt(vtmp); fvec vrcp2powern = v::recip(v_2_0 * vppowern); fvec va = (v_1_0 - vpowminus_powern * vrcp2powern) * vinvsqrt; fvec va_d = vpbeta * v_m0_5 * vinvsqrt * v::recip(vtmp) * (v_1_0 + v_m0_5 * vpowminus_powern * (v_1_0 + vrcp2powern)); vbij = v::blend(vmc2, vbij, va); vbij_d = v::blend(vmc2, vbij_d, va_d); } bvec vmc3 = v::cmplt(vtmp, vpc4) & ~vmc2 & ~vmc1 & mask; if (! v::mask_testz(vmc3)) { vbij = v::blend(vmc3, vbij, v_1_0); vbij_d = v::blend(vmc3, vbij_d, v_0_0); } bvec vmc4 = v::cmple(vtmp, vpc3) & ~vmc3 & ~vmc2 & ~ vmc1 & mask; if (! v::mask_testz(vmc4)) { fvec vpowm1 = pow(vtmp, vppowern - v_1_0); fvec vrcp2powern = v::recip(v_2_0 * vppowern); fvec va = v_1_0 - vtmp * vrcp2powern * vpowm1; fvec va_d = v_m0_5 * vpbeta * vpowm1; vbij = v::blend(vmc4, vbij, va); vbij_d = v::blend(vmc4, vbij_d, va_d); } bvec vmc5 = mask & ~vmc1 & ~vmc2 & ~vmc3 & ~vmc4; if (! v::mask_testz(vmc5)) { fvec vtmp_n = pow(vtmp, vppowern); fvec vpow2 = pow(v_1_0 + vtmp_n, v_m1_0 - v::recip(v_2_0 * vppowern)); fvec va = (v_1_0 + vtmp_n) * vpow2; fvec va_d = v_m0_5 * vpow2 * vtmp_n * v::recip(vzeta_ij); vbij = v::blend(vmc5, vbij, va); vbij_d = v::blend(vmc5, vbij_d, va_d); } fvec vtmp_exp = exp(-vplam1 * vrij); fvec vrep_fforce = vpbiga * vtmp_exp * (vfc_d - vfc * vplam1); fvec vfz_fforce = v_0_5 * vbij * vfa_d; *vfpair = v::mask_add(vfz_fforce, vmask_repulsive, vfz_fforce, vrep_fforce) * v::recip(vrij); *vprefactor = v_m0_5 * vfa * vbij_d; if (EVDWL) { fvec vrep_eng = vfc * vpbiga * vtmp_exp; fvec vfz_eng = v_0_5 * vfa * vbij; *vevdwl = v::mask_add(vfz_eng, vmask_repulsive, vfz_eng, vrep_eng); } } template template void IntelKernelTersoff::attractive_vector( const c_inner_t * param, ivec xjw, bvec mask, fvec vprefactor, fvec vrij, fvec rsq2, fvec vdijx, fvec vdijy, fvec vdijz, fvec dikx, fvec diky, fvec dikz, fvec *fix, fvec *fiy, fvec *fiz, fvec *fjx, fvec *fjy, fvec *fjz, fvec *fkx, fvec *fky, fvec *fkz, fvec *zeta ) { fvec v_1_0 = fvec(1.0); fvec vph = v::zero(), vpc2 = v::zero(), vpd2 = fvec(1.0), vpgamma = v::zero(), vplam3 = v::zero(), vppowermint = v::zero(), vpbigr = v::zero(), vpbigd = fvec(1.0); v::gather_8(xjw, mask, ¶m[0].lam3, &vplam3, &vppowermint, &vpbigr, &vpbigd, &vpc2, &vpd2, &vph, &vpgamma); fvec vrijinv = v::recip(vrij); fvec vrij_hatx = vrijinv * vdijx; fvec vrij_haty = vrijinv * vdijy; fvec vrij_hatz = vrijinv * vdijz; fvec rikinv = invsqrt(rsq2); fvec rik_hatx = rikinv * dikx; fvec rik_haty = rikinv * diky; fvec rik_hatz = rikinv * dikz; fvec vrik = sqrt(rsq2); fvec vcostheta = (vdijx * dikx + vdijy * diky + vdijz * dikz) * v::recip(vrij * vrik); fvec vhcth = vph - vcostheta; fvec vdenominator = v::recip(vpd2 + vhcth * vhcth); fvec vgijk = vpgamma * (v_1_0 + vpc2 * v::recip(vpd2) - vpc2 * vdenominator); fvec vnumerator = fvec(-2.) * vpc2 * vhcth; fvec vgijk_d = vpgamma * vnumerator * vdenominator * vdenominator; fvec varg1 = vplam3 * (vrij - vrik); fvec varg3 = varg1 * varg1 * varg1; bvec mask_ex = v::cmpeq(vppowermint, fvec(3.)); fvec varg = v::blend(mask_ex, varg1, varg3); fvec vex_delr = min(fvec(1.e30), exp(varg)); fvec vex_delr_d_factor = v::blend(mask_ex, v_1_0, fvec(3.0) * varg1 * varg1); fvec vex_delr_d = vplam3 * vex_delr_d_factor * vex_delr; bvec vmask_need_sine = v::cmpnle(vrik, vpbigr - vpbigd) & mask; fvec vfccos; fvec vfc = v_1_0; fvec vfc_d = v::zero(); if (! v::mask_testz(vmask_need_sine)) { fvec vtmp = fvec(MY_PI2) * v::recip(vpbigd); vfc = v::blend(vmask_need_sine, vfc, fvec(0.5) * (v_1_0 - v::sincos(&vfccos, vtmp * (vrik - vpbigr)))); vfc_d = v::blend(vmask_need_sine, vfc_d, fvec(-0.5) * vtmp * vfccos); } fvec vzeta_d_fc = vfc_d * vgijk * vex_delr; fvec vzeta_d_gijk = vfc * vgijk_d * vex_delr; fvec vzeta_d_ex_delr = vfc * vgijk * vex_delr_d; if (ZETA) *zeta = vfc * vgijk * vex_delr; fvec vminus_costheta = - vcostheta; fvec vdcosdrjx = vrijinv * fmadd(vminus_costheta, vrij_hatx, rik_hatx); fvec vdcosdrjy = vrijinv * fmadd(vminus_costheta, vrij_haty, rik_haty); fvec vdcosdrjz = vrijinv * fmadd(vminus_costheta, vrij_hatz, rik_hatz); fvec vdcosdrkx = rikinv * fmadd(vminus_costheta, rik_hatx, vrij_hatx); fvec vdcosdrky = rikinv * fmadd(vminus_costheta, rik_haty, vrij_haty); fvec vdcosdrkz = rikinv * fmadd(vminus_costheta, rik_hatz, vrij_hatz); fvec vdcosdrix = -(vdcosdrjx + vdcosdrkx); fvec vdcosdriy = -(vdcosdrjy + vdcosdrky); fvec vdcosdriz = -(vdcosdrjz + vdcosdrkz); *fix = vprefactor * (vzeta_d_gijk * vdcosdrix + vzeta_d_ex_delr * (rik_hatx - vrij_hatx) - vzeta_d_fc * rik_hatx); *fiy = vprefactor * (vzeta_d_gijk * vdcosdriy + vzeta_d_ex_delr * (rik_haty - vrij_haty) - vzeta_d_fc * rik_haty); *fiz = vprefactor * (vzeta_d_gijk * vdcosdriz + vzeta_d_ex_delr * (rik_hatz - vrij_hatz) - vzeta_d_fc * rik_hatz); *fjx = vprefactor * (vzeta_d_gijk * vdcosdrjx + vzeta_d_ex_delr * vrij_hatx); *fjy = vprefactor * (vzeta_d_gijk * vdcosdrjy + vzeta_d_ex_delr * vrij_haty); *fjz = vprefactor * (vzeta_d_gijk * vdcosdrjz + vzeta_d_ex_delr * vrij_hatz); *fkx = vprefactor * ((vzeta_d_fc - vzeta_d_ex_delr) * rik_hatx + vzeta_d_gijk * vdcosdrkx); *fky = vprefactor * ((vzeta_d_fc - vzeta_d_ex_delr) * rik_haty + vzeta_d_gijk * vdcosdrky); *fkz = vprefactor * ((vzeta_d_fc - vzeta_d_ex_delr) * rik_hatz + vzeta_d_gijk * vdcosdrkz); } #ifdef _LMP_INTEL_OFFLOAD #pragma offload_attribute(pop) #endif #endif diff --git a/src/USER-MANIFOLD/fix_manifoldforce.cpp b/src/USER-MANIFOLD/fix_manifoldforce.cpp index da794e4a4..c3bbc935a 100644 --- a/src/USER-MANIFOLD/fix_manifoldforce.cpp +++ b/src/USER-MANIFOLD/fix_manifoldforce.cpp @@ -1,185 +1,185 @@ /* ---------------------------------------------------------------------- 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 "math.h" -#include "string.h" -#include "stdlib.h" +#include +#include +#include #include "atom.h" #include "update.h" #include "respa.h" #include "error.h" #include "force.h" #include "manifold.h" #include "fix_manifoldforce.h" // For stuff #include "manifold_factory.h" // For constructing manifold using namespace LAMMPS_NS; using namespace FixConst; using namespace user_manifold; // Helper functions for parameters/equal style variables in input script inline bool was_var( const char *arg ) { return strstr( arg, "v_" ) == arg; } inline bool str_eq( const char *str1, const char *str2 ) { return strcmp(str1,str2) == 0; } /* ---------------------------------------------------------------------- */ FixManifoldForce::FixManifoldForce(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { int me = -1; MPI_Comm_rank(world,&me); // Check the min-style: int good_minner = str_eq(update->minimize_style,"hftn") | str_eq(update->minimize_style,"quickmin"); if( !good_minner){ error->warning(FLERR,"Minimizing with fix manifoldforce without hftn or quickmin is fishy"); } // Command is given as // fix manifoldforce manifold_name manifold_args if( narg < 5 ){ error->all(FLERR,"Illegal fix manifoldforce! No manifold given"); } const char *m_name = arg[3]; ptr_m = create_manifold(m_name,lmp,narg,arg); // Construct manifold from factory: if( !ptr_m ){ char msg[2048]; snprintf(msg,2048,"Manifold pointer for manifold '%s' was NULL for some reason", arg[3]); error->all(FLERR,msg); } // After constructing the manifold, you can safely make // room for the parameters nvars = ptr_m->nparams(); if( narg < nvars+4 ){ char msg[2048]; sprintf(msg,"Manifold %s needs at least %d argument(s)!", m_name, nvars); error->all(FLERR,msg); } *(ptr_m->get_params()) = new double[nvars]; if( ptr_m->get_params() == NULL ){ error->all(FLERR,"Parameter pointer was NULL!"); } // This part here stores the names/text of each argument, // determines which params are equal-style variables, // and sets the values of those arguments that were _not_ // equal style vars (so that they are not overwritten each time step). double *params = *(ptr_m->get_params()); for( int i = 0; i < nvars; ++i ){ if( was_var( arg[i+4] ) ) error->all(FLERR,"Equal-style variables not allowed with fix manifoldforce"); // Use force->numeric to trigger an error if arg is not a number. params[i] = force->numeric(FLERR,arg[i+4]); } // Perform any further initialisation for the manifold that depends on params: ptr_m->post_param_init(); } /* ---------------------------------------------------------------------- */ int FixManifoldForce::setmask() { int mask = 0; mask |= POST_FORCE; mask |= POST_FORCE_RESPA; mask |= MIN_POST_FORCE; return mask; } /* ---------------------------------------------------------------------- */ void FixManifoldForce::setup(int vflag) { if (strstr(update->integrate_style,"verlet")) post_force(vflag); else { int nlevels_respa = ((Respa *) update->integrate)->nlevels; for (int ilevel = 0; ilevel < nlevels_respa; ilevel++) { ((Respa *) update->integrate)->copy_flevel_f(ilevel); post_force_respa(vflag,ilevel,0); ((Respa *) update->integrate)->copy_f_flevel(ilevel); } } } /* ---------------------------------------------------------------------- */ void FixManifoldForce::min_setup(int vflag) { post_force(vflag); } /* ---------------------------------------------------------------------- */ void FixManifoldForce::post_force(int vflag) { double **x = atom->x; double **f = atom->f; int *mask = atom->mask; int nlocal = atom->nlocal; double n[3]; double invn2; double dot; for (int i = 0; i < nlocal; i++){ if (mask[i] & groupbit) { // Determine normal of particle: ptr_m->n(x[i],n); invn2 = 1.0 / ( n[0]*n[0] + n[1]*n[1] + n[2]*n[2] ); dot = f[i][0]*n[0] + f[i][1]*n[1] + f[i][2]*n[2]; f[i][0] -= dot*n[0] * invn2; f[i][1] -= dot*n[1] * invn2; f[i][2] -= dot*n[2] * invn2; } } } /* ---------------------------------------------------------------------- */ void FixManifoldForce::post_force_respa(int vflag, int ilevel, int iloop) { post_force(vflag); } /* ---------------------------------------------------------------------- */ void FixManifoldForce::min_post_force(int vflag) { post_force(vflag); } diff --git a/src/USER-MANIFOLD/fix_nve_manifold_rattle.cpp b/src/USER-MANIFOLD/fix_nve_manifold_rattle.cpp index 246f7cc66..e27762a7d 100644 --- a/src/USER-MANIFOLD/fix_nve_manifold_rattle.cpp +++ b/src/USER-MANIFOLD/fix_nve_manifold_rattle.cpp @@ -1,644 +1,644 @@ /* ---------------------------------------------------------------------- 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. ----------------------------------------------------------------------- This file is a part of the USER-MANIFOLD package. Copyright (2013-2014) Stefan Paquay, Eindhoven University of Technology. License: GNU General Public License. See the README file in the top-level LAMMPS directory. This file is part of the user-manifold package written by Stefan Paquay at the Eindhoven University of Technology. This module makes it possible to do MD with particles constrained to pretty arbitrary manifolds characterised by some constraint function g(x,y,z) = 0 and its normal grad(g). The number of manifolds available right now is limited but can be extended straightforwardly by making a new class that inherits from manifold and implements all pure virtual methods. Thanks to Remy Kusters for beta-testing! ------------------------------------------------------------------------- */ -#include "stdio.h" -#include "stdlib.h" -#include "string.h" +#include +#include +#include #include "atom.h" #include "force.h" #include "update.h" #include "respa.h" #include "error.h" #include "group.h" -#include "math.h" +#include #include "input.h" #include "variable.h" #include "citeme.h" #include "memory.h" #include "comm.h" #include "fix_nve_manifold_rattle.h" #include "manifold_factory.h" #include "manifold.h" using namespace LAMMPS_NS; using namespace FixConst; using namespace user_manifold; enum { CONST, EQUAL }; // For treating the variables. static const char* cite_fix_nve_manifold_rattle = "fix nve/manifold/rattle command:\n\n" "@article{paquay-2016,\n" " author = {Paquay, Stefan and Kusters, Remy},\n" " doi = {10.1016/j.bpj.2016.02.017},\n" " issn = {0006-3495},\n" " journal = {Biophysical Journal},\n" " month = apr,\n" " number = {6},\n" " pages = {1226--1233},\n" " title = {{A Method for Molecular Dynamics on Curved Surfaces}},\n" " volume = {110},\n" " year = {2016}\n" "}\n\n"; /* ----------------------------------------------------------------------------- ---------------------------------------------------------------------------*/ FixNVEManifoldRattle::FixNVEManifoldRattle( LAMMPS *lmp, int &narg, char **arg, int error_on_unknown_keyword ) : Fix(lmp,narg,arg) { if( lmp->citeme) lmp->citeme->add(cite_fix_nve_manifold_rattle); if( narg < 6 ) error->all(FLERR, "Illegal fix nve/manifold/rattle command"); // Set all bits/settings: time_integrate = 1; dynamic_group_allow = 1; size_vector = 0; dof_flag = 1; nevery = 0; dtv = dtf = 0; tolerance = force->numeric( FLERR, arg[3] ); max_iter = force->numeric( FLERR, arg[4] ); ptr_m = create_manifold(arg[5], lmp, narg, arg); if( !ptr_m ){ error->all(FLERR,"Error creating manifold pointer"); } nvars = ptr_m->nparams(); tstrs = new char*[nvars]; tvars = new int[nvars]; tstyle = new int[nvars]; is_var = new int[nvars]; if( !tstrs || !tvars || !tstyle || !is_var ){ error->all(FLERR, "Error creating manifold arg arrays"); } // Loop over manifold args: for( int i = 0; i < nvars; ++i ){ int len = 0, offset = 0; if( was_var( arg[i+6] ) ){ len = strlen(arg[i+6]) - 1; // -1 because -2 for v_, +1 for \0. is_var[i] = 1; offset = 2; }else{ force->numeric(FLERR,arg[i+6]); // Check if legal number. len = strlen( arg[i+6] ) + 1; // +1 for \0. is_var[i] = 0; } tstrs[i] = new char[len]; if( tstrs[i] == NULL ) error->all(FLERR,"Error allocating space for args."); strcpy( tstrs[i], arg[i+6] + offset ); } *ptr_m->get_params() = new double[nvars]; if( !(*ptr_m->get_params()) ) error->all(FLERR,"Failed to allocate params!"); for( int i = 0; i < nvars; ++i ){ // If param i was variable type, it will be set later... (*ptr_m->get_params())[i] = is_var[i] ? 0.0 : force->numeric( FLERR, arg[i+6] ); } ptr_m->post_param_init(); // Loop over rest of args: int argi = 6 + nvars; while( argi < narg ){ if( strcmp(arg[argi], "every") == 0 ){ nevery = force->inumeric(FLERR,arg[argi+1]); argi += 2; }else if( error_on_unknown_keyword ){ char msg[2048]; sprintf(msg,"Error parsing arg \"%s\".\n", arg[argi]); error->all(FLERR, msg); }else{ argi += 1; } } } /* ----------------------------------------------------------------------------- ---------------------------------------------------------------------------*/ FixNVEManifoldRattle::~FixNVEManifoldRattle() { if( tstrs ){ for( int i = 0; i < nvars; ++i ){ delete [] tstrs[i]; } delete [] tstrs; } if( tvars ) delete [] tvars; if( tstyle ) delete [] tstyle; if( is_var ) delete [] is_var; } /* ----------------------------------------------------------------------------- ---------------------------------------------------------------------------*/ void FixNVEManifoldRattle::reset_dt() { dtv = update->dt; dtf = 0.5 * update->dt * force->ftm2v; } void FixNVEManifoldRattle::print_stats( const char *header ) { double n = stats.natoms; if( n > 0 ){ stats.x_iters_per_atom += stats.x_iters / n; stats.v_iters_per_atom += stats.v_iters / n; } double x_iters = 0, v_iters = 0; bigint ntimestep = update->ntimestep; int me = -1; MPI_Comm_rank(world,&me); MPI_Allreduce(&stats.x_iters_per_atom,&x_iters,1,MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(&stats.v_iters_per_atom,&v_iters,1,MPI_DOUBLE,MPI_SUM,world); // Set iters back to zero: stats.x_iters_per_atom = stats.x_iters = 0; stats.v_iters_per_atom = stats.v_iters = 0; if( me == 0 ){ double inv_tdiff = 1.0/( static_cast(ntimestep) - stats.last_out ); stats.last_out = ntimestep; fprintf(screen, "%s stats for time step " BIGINT_FORMAT " on %d atoms:\n", header, ntimestep, stats.natoms); fprintf(screen, " iters/atom: x = %f, v = %f, dofs removed %d", x_iters * inv_tdiff, v_iters * inv_tdiff, stats.dofs_removed); fprintf(screen,"\n"); } } /* ----------------------------------------------------------------------------- ---------------------------------------------------------------------------*/ int FixNVEManifoldRattle::was_var( const char *str ) { if( strlen(str) > 2 ){ return (str[0] == 'v') && (str[1] == '_'); }else{ return 0; } } /* ----------------------------------------------------------------------------- ---------------------------------------------------------------------------*/ int FixNVEManifoldRattle::setmask() { int mask = 0; mask |= INITIAL_INTEGRATE; mask |= FINAL_INTEGRATE; if( nevery > 0 ) mask |= END_OF_STEP; return mask; } /* ----------------------------------------------------------------------------- ---------------------------------------------------------------------------*/ void FixNVEManifoldRattle::init() { // Makes sure the manifold params are set initially. update_var_params(); reset_dt(); } void FixNVEManifoldRattle::update_var_params() { if( nevery > 0 ){ stats.x_iters = 0; stats.v_iters = 0; stats.natoms = 0; stats.x_iters_per_atom = 0.0; stats.v_iters_per_atom = 0.0; } double **ptr_params = ptr_m->get_params(); for( int i = 0; i < nvars; ++i ){ if( is_var[i] ){ tvars[i] = input->variable->find(tstrs[i]); if( tvars[i] < 0 ){ error->all(FLERR, "Variable name for fix nve/manifold/rattle does not exist"); } if( input->variable->equalstyle(tvars[i]) ){ tstyle[i] = EQUAL; double new_val = input->variable->compute_equal(tvars[i]); // fprintf( stdout, "New value of var %d is now %f\n", i+1, new_val ); *(ptr_params[i]) = new_val; }else{ error->all(FLERR, "Variable for fix nve/manifold/rattle is invalid style"); } } } } /* ----------------------------------------------------------------------------- ---------------------------------------------------------------------------*/ int FixNVEManifoldRattle::dof(int igroup) { int *mask = atom->mask; int nlocal = atom->nlocal; int natoms = 0; for( int i = 0; i < nlocal; ++i ){ if(mask[i] & groupbit) ++natoms; } int dofs; MPI_Allreduce( &natoms, &dofs, 1, MPI_INT, MPI_SUM, world ); // Make sure that, if there is just no or one atom, no dofs are subtracted, // since for the first atom already 3 dofs are subtracted because of the // centre of mass corrections: if( dofs <= 1 ) dofs = 0; stats.dofs_removed = dofs; return dofs; } /* ----------------------------------------------------------------------------- ---------------------------------------------------------------------------*/ double FixNVEManifoldRattle::memory_usage() { double bytes = 0.0; bytes += sizeof(statistics); bytes += sizeof(*ptr_m) + sizeof(ptr_m); bytes += nvars*sizeof(double) + sizeof(double*); bytes += nvars*( sizeof(char*) + 3*sizeof(int) ); return bytes; } /* ----------------------------------------------------------------------------- ---------------------------------------------------------------------------*/ void FixNVEManifoldRattle::initial_integrate(int vflag) { update_var_params(); nve_x_rattle(igroup, groupbit); } /* ----------------------------------------------------------------------------- ---------------------------------------------------------------------------*/ void FixNVEManifoldRattle::final_integrate() { nve_v_rattle(igroup, groupbit); } /* ----------------------------------------------------------------------------- ---------------------------------------------------------------------------*/ void FixNVEManifoldRattle::end_of_step() { print_stats( "nve/manifold/rattle" ); } /* ----------------------------------------------------------------------------- ---------------------------------------------------------------------------*/ void FixNVEManifoldRattle::nve_x_rattle(int igroup, int groupbit) { double dtfm; // update v and x of atoms in group double **x = atom->x; double **v = atom->v; double **f = atom->f; double *rmass = atom->rmass; double *mass = atom->mass; int *type = atom->type; int *mask = atom->mask; int nlocal = atom->nlocal; int natoms = 0; if (igroup == atom->firstgroup){ nlocal = atom->nfirst; } if (rmass) { for (int i = 0; i < nlocal; i++){ if (mask[i] & groupbit){ natoms++; dtfm = dtf / rmass[i]; rattle_manifold_x( x[i], v[i], f[i], dtv, dtfm, atom->tag[i] ); } } } else { for (int i = 0; i < nlocal; i++){ if (mask[i] & groupbit) { natoms++; dtfm = dtf / mass[type[i]]; rattle_manifold_x( x[i], v[i], f[i], dtv, dtfm, atom->tag[i] ); } } } if( nevery > 0 ){ // Count ALL atoms this fix works on: MPI_Allreduce(&natoms,&stats.natoms,1,MPI_INT,MPI_SUM,world); } } /* ----------------------------------------------------------------------------- ---------------------------------------------------------------------------*/ void FixNVEManifoldRattle::nve_v_rattle(int igroup, int groupbit) { double dtfm; // update v of atoms in group double **x = atom->x; double **v = atom->v; double **f = atom->f; double *rmass = atom->rmass; double *mass = atom->mass; int *type = atom->type; int *mask = atom->mask; int nlocal = atom->nlocal; if (igroup == atom->firstgroup) nlocal = atom->nfirst; if (rmass) { for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { dtfm = dtf / rmass[i]; rattle_manifold_v( v[i], f[i], x[i], dtfm, atom->tag[i] ); } } } else { for (int i = 0; i < nlocal; i++){ if (mask[i] & groupbit) { dtfm = dtf / mass[type[i]]; rattle_manifold_v( v[i], f[i], x[i], dtfm, atom->tag[i] ); } } } } /* ----------------------------------------------------------------------------- ---------------------------------------------------------------------------*/ void FixNVEManifoldRattle::rattle_manifold_x(double *x, double *v, double *f, double dtv, double dtfm, tagint tagi ) { /* A RATTLE update for the position constraint. Original update is x += dtv * v_1/2 Now you do v_1/2(lambda) = v_0 + dtfm * ( f + lambda*n_old ) and solve xold - xnew + dtv * v_1/2(lambda) = 0 g(xnew) = 0 for x and lambda. The lambda you find then gives v_1/2 as well. */ double xo[3]; // Previous position to update from. double vo[3]; // Previous velocity to update from. double l = 0; // Lagrangian multiplier for constraint forces. double R[4]; // System that is 0. double dx[4]; // Update that follows from Newton iteration. double no[3]; // Normal at xo. double nn[3]; // Normal at x, the new position. double res; // Residual. int iters = 0; // Iterations used double c = dtfm*dtv; // Used for iterating in the Newton loop: double no_nn, nn_R; vo[0] = v[0]; vo[1] = v[1]; vo[2] = v[2]; xo[0] = x[0]; xo[1] = x[1]; xo[2] = x[2]; double gg = ptr_m->g_and_n(x,no); nn[0] = no[0]; nn[1] = no[1]; nn[2] = no[2]; double vt[3]; vt[0] = vo[0] + dtfm*f[0]; vt[1] = vo[1] + dtfm*f[1]; vt[2] = vo[2] + dtfm*f[2]; double no_dt[3]; no_dt[0] = dtfm*no[0]; no_dt[1] = dtfm*no[1]; no_dt[2] = dtfm*no[2]; // Assume that no_nn is roughly constant during iteration: const double c_inv = 1.0 / c; while ( 1 ) { v[0] = vt[0] - l*no_dt[0]; v[1] = vt[1] - l*no_dt[1]; v[2] = vt[2] - l*no_dt[2]; R[0] = xo[0] - x[0] + dtv * v[0]; R[1] = xo[1] - x[1] + dtv * v[1]; R[2] = xo[2] - x[2] + dtv * v[2]; R[3] = gg; // Analytic solution to system J*(dx,dy,dz,dl)^T = R // no_nn = no[0]*nn[0] + no[1]*nn[1] + no[2]*nn[2]; nn_R = nn[0]*R[0] + nn[1]*R[1] + nn[2]*R[2]; no_nn = no[0]*nn[0] + no[1]*nn[1] + no[2]*nn[2]; double n_inv = 1.0 / no_nn; // fprintf( screen, "nn_R = %f, no_nn = %f\n", nn_R, no_nn ); dx[3] = -nn_R - R[3]; dx[3] *= n_inv; dx[0] = -R[0] - no[0]*dx[3]; dx[1] = -R[1] - no[1]*dx[3]; dx[2] = -R[2] - no[2]*dx[3]; dx[3] *= c_inv; x[0] -= dx[0]; x[1] -= dx[1]; x[2] -= dx[2]; l -= dx[3]; res = infnorm<4>(R); ++iters; if( (res < tolerance) || (iters >= max_iter) ) break; // Update nn and g. gg = ptr_m->g(x); ptr_m->n(x,nn); // gg = ptr_m->g(x); } if( iters >= max_iter && res > tolerance ){ char msg[2048]; sprintf(msg,"Failed to constrain atom %d (x = (%f, %f, %f)! res = %e, iters = %d\n", tagi, x[0], x[1], x[2], res, iters); error->one(FLERR,msg); } // "sync" x and v: v[0] = vt[0] - l*no_dt[0]; v[1] = vt[1] - l*no_dt[1]; v[2] = vt[2] - l*no_dt[2]; stats.x_iters += iters; } /* ----------------------------------------------------------------------------- ---------------------------------------------------------------------------*/ void FixNVEManifoldRattle::rattle_manifold_v(double *v, double *f, double *x, double dtfm, tagint tagi ) { /* The original update was v[i][0] += dtfm * f[i][0]; v[i][1] += dtfm * f[i][1]; v[i][2] += dtfm * f[i][2]; Now you add the rattle-like update: vold - vnew + dtfm * F + mu * n_new = 0 dot( vnew, n_new ) = 0 */ double vo[3]; // V at t + 1/2 dt double l = 0; // Lagrangian multiplier for constraint forces. double R[4]; // System that is 0. double dv[4]; // Update that follows from Newton iteration. double n[3]; // Normal. double res; // Residual. int iters = 0; // Iterations used double c = dtfm; // Used for iterating in the Newton loop: double nn2, nn_R; vo[0] = v[0]; vo[1] = v[1]; vo[2] = v[2]; // Initial guess is unconstrained update: v[0] += dtfm*f[0]; v[1] += dtfm*f[1]; v[2] += dtfm*f[2]; ptr_m->n(x,n); double vt[3]; vt[0] = vo[0] + dtfm*f[0]; vt[1] = vo[1] + dtfm*f[1]; vt[2] = vo[2] + dtfm*f[2]; double no_dt[3]; no_dt[0] = dtfm*n[0]; no_dt[1] = dtfm*n[1]; no_dt[2] = dtfm*n[2]; nn2 = n[0]*n[0] + n[1]*n[1] + n[2]*n[2]; const double n_inv = 1.0 / nn2; const double c_inv = 1.0 / c; do{ R[0] = vt[0] - v[0] - l * no_dt[0]; R[1] = vt[1] - v[1] - l * no_dt[1]; R[2] = vt[2] - v[2] - l * no_dt[2]; R[3] = v[0]*n[0] + v[1]*n[1] + v[2]*n[2]; // Analytic solution to system J*(dx,dy,dz,dl)^T = R nn_R = n[0]*R[0] + n[1]*R[1] + n[2]*R[2]; dv[3] = -nn_R - R[3]; dv[3] *= n_inv; dv[0] = -n[0]*dv[3] - R[0]; dv[1] = -n[1]*dv[3] - R[1]; dv[2] = -n[2]*dv[3] - R[2]; dv[3] *= c_inv; v[0] -= dv[0]; v[1] -= dv[1]; v[2] -= dv[2]; l -= dv[3]; res = infnorm<4>(R); ++iters; }while( (res > tolerance) && (iters < max_iter) ); if( iters >= max_iter && res >= tolerance ){ char msg[2048]; sprintf(msg,"Failed to constrain atom %d (x = (%f, %f, %f)! res = %e, iters = %d\n", tagi, x[0], x[1], x[2], res, iters); error->all(FLERR,msg); } stats.v_iters += iters; } diff --git a/src/USER-MANIFOLD/fix_nvt_manifold_rattle.cpp b/src/USER-MANIFOLD/fix_nvt_manifold_rattle.cpp index b0109d16f..38e8c6a26 100644 --- a/src/USER-MANIFOLD/fix_nvt_manifold_rattle.cpp +++ b/src/USER-MANIFOLD/fix_nvt_manifold_rattle.cpp @@ -1,416 +1,416 @@ /* ---------------------------------------------------------------------- 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. ----------------------------------------------------------------------- This file is a part of the USER-MANIFOLD package. Copyright (2013-2014) Stefan Paquay, Eindhoven University of Technology. License: GNU General Public License. See the README file in the top-level LAMMPS directory. This file is part of the user-manifold package written by Stefan Paquay at the Eindhoven University of Technology. This module makes it possible to do MD with particles constrained to pretty arbitrary manifolds characterised by some constraint function g(x,y,z) = 0 and its normal grad(g). The number of manifolds available right now is limited but can be extended straightforwardly by making a new class that inherits from manifold and implements all pure virtual methods. Thanks to Remy Kusters for beta-testing! ------------------------------------------------------------------------- */ -#include "stdio.h" -#include "stdlib.h" -#include "string.h" +#include +#include +#include #include "atom.h" #include "force.h" #include "update.h" #include "respa.h" #include "error.h" #include "group.h" -#include "math.h" +#include #include "input.h" #include "variable.h" #include "citeme.h" #include "memory.h" #include "comm.h" #include "modify.h" #include "compute.h" #include "fix_nvt_manifold_rattle.h" #include "manifold.h" using namespace LAMMPS_NS; using namespace FixConst; using namespace user_manifold; enum {CONSTANT,EQUAL}; enum {NOBIAS,BIAS}; static const char* cite_fix_nvt_manifold_rattle = "fix nvt/manifold/rattle command:\n\n" "@article{paquay-2016,\n" " author = {Paquay, Stefan and Kusters, Remy},\n" " doi = {10.1016/j.bpj.2016.02.017},\n" " issn = {0006-3495},\n" " journal = {Biophysical Journal},\n" " month = apr,\n" " number = {6},\n" " pages = {1226--1233},\n" " title = {{A Method for Molecular Dynamics on Curved Surfaces}},\n" " volume = {110},\n" " year = {2016}\n" "}\n\n"; /* ---------------------------------------------------------------------- */ FixNVTManifoldRattle::FixNVTManifoldRattle(LAMMPS *lmp, int narg, char **arg, int error_on_unknown_keyword ) : FixNVEManifoldRattle(lmp,narg,arg, 0) { if (lmp->citeme) lmp->citeme->add(cite_fix_nvt_manifold_rattle); if( narg < 6 ) error->all(FLERR,"Illegal fix nvt/manifold/rattle command"); // Set all bits/settings: dof_flag = 1; dthalf = dt4 = dt8 = 0; t_start = t_stop = t_period = t_current = t_target = ke_target = 0.0; t_freq = drag = tdrag_factor = 0; boltz = force->boltz, nktv2p = force->nktv2p; tdof = 0; mtchain = 3; factor_eta = 0.0; which = got_temp = 0; int argi = 6 + ptr_m->nparams(); while( argi < narg ) { if( strcmp( arg[argi], "temp") == 0 ){ if( argi+3 >= narg ) error->all(FLERR,"Keyword 'temp' needs 3 arguments"); t_start = force->numeric(FLERR, arg[argi+1]); t_stop = force->numeric(FLERR, arg[argi+2]); t_period = force->numeric(FLERR, arg[argi+3]); t_target = t_start; got_temp = 1; argi += 4; }else if( strcmp( arg[argi], "tchain" ) == 0 ){ if( argi+1 >= narg ) error->all(FLERR,"Keyword 'tchain' needs 1 argument"); mtchain = force->inumeric(FLERR, arg[argi+1]); argi += 2; }else if( error_on_unknown_keyword ){ char msg[2048]; sprintf(msg,"Error parsing arg \"%s\".\n", arg[argi]); error->all(FLERR, msg); }else{ argi += 1; } } reset_dt(); if( !got_temp ) error->all(FLERR,"Fix nvt/manifold/rattle needs 'temp'!"); if( t_period < 0.0 ){ error->all(FLERR,"Fix nvt/manifold/rattle damping parameter must be > 0.0"); } // Create temperature compute: const char *fix_id = arg[1]; int n = strlen(fix_id)+6; id_temp = new char[n]; strcpy(id_temp,fix_id); strcat(id_temp,"_temp"); char **newarg = new char*[3]; newarg[0] = id_temp; newarg[1] = group->names[igroup]; newarg[2] = (char*) "temp"; modify->add_compute(3,newarg); delete [] newarg; int icompute = modify->find_compute(id_temp); if( icompute < 0 ){ error->all(FLERR,"Temperature ID for fix nvt/manifold/rattle " "does not exist"); } temperature = modify->compute[icompute]; if( temperature->tempbias ) which = BIAS; else which = NOBIAS; // Set t_freq from t_period t_freq = 1.0 / t_period; // Init Nosé-Hoover chain: eta = new double[mtchain]; eta_dot = new double[mtchain+1]; eta_dotdot = new double[mtchain]; eta_mass = new double[mtchain]; eta_dot[mtchain] = 0.0; eta_dot[mtchain] = 0.0; for( int ich = 0; ich < mtchain; ++ich ){ eta[ich] = eta_dot[ich] = eta_dotdot[ich] = 0.0; } } /* ---------------------------------------------------------------------- */ FixNVTManifoldRattle::~FixNVTManifoldRattle() { // Deallocate heap-allocated objects. if( eta ) delete[] eta; if( eta_dot ) delete[] eta_dot; if( eta_dotdot ) delete[] eta_dotdot; if( eta_mass ) delete[] eta_mass; modify->delete_compute(id_temp); if( id_temp ) delete[] id_temp; } int FixNVTManifoldRattle::setmask() { int mask = 0; mask |= INITIAL_INTEGRATE; mask |= FINAL_INTEGRATE; if( nevery > 0 ) mask |= END_OF_STEP; return mask; } /* -------------------------------------------------------------------------- Check that force modification happens before position and velocity update. Make sure respa is not used. ------------------------------------------------------------------------- */ void FixNVTManifoldRattle::init() { // Makes sure the manifold params are set initially. update_var_params(); int icompute = modify->find_compute(id_temp); if( icompute < 0 ){ error->all(FLERR,"Temperature ID for fix nvt/manifold/rattle " "does not exist"); } temperature = modify->compute[icompute]; if( temperature->tempbias ) which = BIAS; else which = NOBIAS; } void FixNVTManifoldRattle::setup(int vflag) { compute_temp_target(); t_current = temperature->compute_scalar(); tdof = temperature->dof; // Compute/set eta-masses: double inv_t_freq2 = 1.0 / (t_freq*t_freq); eta_mass[0] = tdof * boltz * t_target * inv_t_freq2; for( int ich = 1; ich < mtchain; ++ich ){ eta_mass[ich] = boltz * t_target * inv_t_freq2; } for( int ich = 1; ich < mtchain; ++ich ){ eta_dotdot[ich] = (eta_mass[ich-1]*eta_dot[ich-1]*eta_dot[ich-1] - boltz * t_target ) / eta_mass[ich]; } } void FixNVTManifoldRattle::compute_temp_target() { t_current = temperature->compute_scalar(); tdof = temperature->dof; double delta = update->ntimestep - update->beginstep; if (delta != 0.0){ delta /= update->endstep - update->beginstep; } tdof = temperature->dof; t_target = t_start + delta * (t_stop-t_start); ke_target = tdof * boltz * t_target; } void FixNVTManifoldRattle::nhc_temp_integrate() { int ich; // t_current = temperature->compute_scalar(); // tdof = temperature->dof; compute_temp_target(); double expfac, kecurrent = tdof * boltz * t_current; double inv_t_freq2 = 1.0 / (t_freq*t_freq); eta_mass[0] = tdof * boltz * t_target * inv_t_freq2; for( int ich = 1; ich < mtchain; ++ich ){ eta_mass[ich] = boltz * t_target * inv_t_freq2; } if( eta_mass[0] > 0.0 ){ eta_dotdot[0] = (kecurrent - ke_target)/eta_mass[0]; }else{ eta_dotdot[0] = 0; } for( ich = mtchain-1; ich > 0; --ich ){ expfac = exp(-dt8*eta_dot[ich+1]); eta_dot[ich] *= expfac; eta_dot[ich] += eta_dotdot[ich] * dt4; eta_dot[ich] *= tdrag_factor * expfac; } expfac = exp(-dt8*eta_dot[1]); eta_dot[0] *= expfac; eta_dot[0] += eta_dotdot[0] * dt4; eta_dot[0] *= tdrag_factor * expfac; factor_eta = exp(-dthalf*eta_dot[0]); if( factor_eta == 0 ){ char msg[2048]; sprintf(msg, "WTF, factor_eta is 0! dthalf = %f, eta_dot[0] = %f", dthalf, eta_dot[0]); error->all(FLERR,msg); } nh_v_temp(); t_current *= factor_eta*factor_eta; kecurrent = tdof * boltz * t_current; if( eta_mass[0] > 0.0 ){ eta_dotdot[0] = (kecurrent - ke_target) / eta_mass[0]; }else{ eta_dotdot[0] = 0.0; } for( int ich = 1; ich < mtchain; ++ich ){ eta[ich] += dthalf*eta_dot[ich]; } eta_dot[0] *= expfac; eta_dot[0] += eta_dotdot[0]*dt4; eta_dot[0] *= expfac; for( int ich = 1; ich < mtchain; ++ich ){ expfac = exp(-dt8*eta_dot[ich+1]); eta_dot[ich] *= expfac; eta_dotdot[ich] = (eta_mass[ich-1]*eta_dot[ich-1]*eta_dot[ich-1] - boltz*t_target) / eta_mass[ich]; eta_dot[ich] *= eta_dotdot[ich] * dt4; eta_dot[ich] *= expfac; } } void FixNVTManifoldRattle::nh_v_temp() { double **v = atom->v; int *mask = atom->mask; int nlocal = atom->nlocal; if( igroup == atom->firstgroup) nlocal = atom->nfirst; if( which == NOBIAS ){ for( int i = 0; i < nlocal; ++i ){ if( mask[i] & groupbit ){ v[i][0] *= factor_eta; v[i][1] *= factor_eta; v[i][2] *= factor_eta; } } }else if( which == BIAS ){ for( int i = 0; i < nlocal; ++i ){ if( mask[i] & groupbit ){ temperature->remove_bias(i,v[i]); v[i][0] *= factor_eta; v[i][1] *= factor_eta; v[i][2] *= factor_eta; temperature->restore_bias(i,v[i]); } } } } // Most of this logic is based on fix_nh: void FixNVTManifoldRattle::initial_integrate(int vflag) { update_var_params(); compute_temp_target(); nhc_temp_integrate(); nve_x_rattle(igroup, groupbit); } void FixNVTManifoldRattle::final_integrate() { nve_v_rattle(igroup, groupbit); nhc_temp_integrate(); } /* ---------------------------------------------------------------------- */ void FixNVTManifoldRattle::reset_dt() { FixNVEManifoldRattle::reset_dt(); dthalf = 0.5 * update->dt; dt4 = 0.25 * update->dt; dt8 = 0.125 * update->dt; tdrag_factor = 1.0 - (update->dt * t_freq * drag); } double FixNVTManifoldRattle::memory_usage() { double bytes = FixNVEManifoldRattle::memory_usage(); bytes += (4*mtchain+1)*sizeof(double); return bytes; } diff --git a/src/USER-MISC/fix_flow_gauss.cpp b/src/USER-MISC/fix_flow_gauss.cpp index 129a4aa0e..ad4c78f87 100644 --- a/src/USER-MISC/fix_flow_gauss.cpp +++ b/src/USER-MISC/fix_flow_gauss.cpp @@ -1,219 +1,246 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing authors: Steven E. Strong and Joel D. Eaves Joel.Eaves@Colorado.edu ------------------------------------------------------------------------- */ #include #include #include "fix_flow_gauss.h" #include "atom.h" #include "force.h" #include "group.h" #include "comm.h" #include "update.h" #include "domain.h" #include "error.h" #include "citeme.h" +#include "respa.h" using namespace LAMMPS_NS; using namespace FixConst; static const char cite_flow_gauss[] = "Gaussian dynamics package:\n\n" "@Article{strong_atomistic_2016,\n" "title = {Atomistic Hydrodynamics and the Dynamical Hydrophobic Effect in Porous Graphene},\n" "volume = {7},\n" "number = {10},\n" "issn = {1948-7185},\n" "url = {http://dx.doi.org/10.1021/acs.jpclett.6b00748},\n" "doi = {10.1021/acs.jpclett.6b00748},\n" "urldate = {2016-05-10},\n" "journal = {J. Phys. Chem. Lett.},\n" "author = {Strong, Steven E. and Eaves, Joel D.},\n" "year = {2016},\n" "pages = {1907--1912}\n" "}\n\n"; FixFlowGauss::FixFlowGauss(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { if (lmp->citeme) lmp->citeme->add(cite_flow_gauss); if (narg < 6) error->all(FLERR,"Not enough input arguments"); // a group which conserves momentum must also conserve particle number dynamic_group_allow = 0; scalar_flag = 1; vector_flag = 1; extscalar = 1; extvector = 1; size_vector = 3; global_freq = 1; //data available every timestep + respa_level_support = 1; + //default respa level=outermost level is set in init() dimension = domain->dimension; //get inputs int tmpFlag; for (int ii=0; ii<3; ii++) { tmpFlag=force->inumeric(FLERR,arg[3+ii]); if (tmpFlag==1 || tmpFlag==0) flow[ii]=tmpFlag; else error->all(FLERR,"Constraint flags must be 1 or 0"); } // by default, do not compute work done workflag=0; // process optional keyword int iarg = 6; while (iarg < narg) { if ( strcmp(arg[iarg],"energy") == 0 ) { if ( iarg+2 > narg ) error->all(FLERR,"Illegal energy keyword"); if ( strcmp(arg[iarg+1],"yes") == 0 ) workflag = 1; else if ( strcmp(arg[iarg+1],"no") != 0 ) error->all(FLERR,"Illegal energy keyword"); iarg += 2; } else error->all(FLERR,"Illegal fix flow/gauss command"); } //error checking if (dimension == 2) { if (flow[2]) error->all(FLERR,"Can't constrain z flow in 2d simulation"); } dt=update->dt; pe_tot=0.0; } /* ---------------------------------------------------------------------- */ int FixFlowGauss::setmask() { int mask = 0; mask |= POST_FORCE; mask |= THERMO_ENERGY; + mask |= POST_FORCE_RESPA; return mask; } +/* ---------------------------------------------------------------------- */ + +void FixFlowGauss::init() +{ + //if respa level specified by fix_modify, then override default (outermost) + //if specified level too high, set to max level + if (strstr(update->integrate_style,"respa")) { + ilevel_respa = ((Respa *) update->integrate)->nlevels-1; + if (respa_level >= 0) + ilevel_respa = MIN(respa_level,ilevel_respa); + } +} + /* ---------------------------------------------------------------------- setup is called after the initial evaluation of forces before a run, so we must remove the total force here too ------------------------------------------------------------------------- */ void FixFlowGauss::setup(int vflag) { //need to compute work done if set fix_modify energy yes if (thermo_energy) workflag=1; //get total mass of group mTot=group->mass(igroup); if (mTot <= 0.0) error->all(FLERR,"Invalid group mass in fix flow/gauss"); - post_force(vflag); + if (strstr(update->integrate_style,"respa")) { + ((Respa *) update->integrate)->copy_flevel_f(ilevel_respa); + post_force_respa(vflag,ilevel_respa,0); + ((Respa *) update->integrate)->copy_f_flevel(ilevel_respa); + } + else + post_force(vflag); } /* ---------------------------------------------------------------------- this is where Gaussian dynamics constraint is applied ------------------------------------------------------------------------- */ void FixFlowGauss::post_force(int vflag) { double **f = atom->f; double **v = atom->v; int *mask = atom->mask; int *type = atom->type; double *mass = atom->mass; double *rmass = atom->rmass; int nlocal = atom->nlocal; int ii,jj; //find the total force on all atoms - //initialize to zero double f_thisProc[3]; for (ii=0; ii<3; ii++) f_thisProc[ii]=0.0; //add all forces on each processor for(ii=0; ii #include "fix_wall_gran_omp.h" #include "atom.h" #include "memory.h" #include "neighbor.h" #include "update.h" using namespace LAMMPS_NS; using namespace FixConst; -enum{XPLANE=0,YPLANE=1,ZPLANE=2,ZCYLINDER}; // XYZ PLANE need to be 0,1,2 -enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY}; +enum{XPLANE=0,YPLANE=1,ZPLANE=2,ZCYLINDER,REGION}; // XYZ PLANE need to be 0,1,2 +enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY,BONDED_HISTORY}; #define BIG 1.0e20 /* ---------------------------------------------------------------------- */ FixWallGranOMP::FixWallGranOMP(LAMMPS *lmp, int narg, char **arg) : FixWallGran(lmp, narg, arg) { } /* ---------------------------------------------------------------------- */ void FixWallGranOMP::post_force(int vflag) { double vwall[3]; // if just reneighbored: // update rigid body masses for owned atoms if using FixRigid // body[i] = which body atom I is in, -1 if none // mass_body = mass of each rigid body if (neighbor->ago == 0 && fix_rigid) { int tmp; const int * const body = (const int * const) fix_rigid->extract("body",tmp); double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); if (atom->nmax > nmax) { memory->destroy(mass_rigid); nmax = atom->nmax; memory->create(mass_rigid,nmax,"wall/gran:mass_rigid"); } const int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; else mass_rigid[i] = 0.0; } } // set position of wall to initial settings and velocity to 0.0 // if wiggle or shear, set wall position and velocity accordingly double wlo = lo; double whi = hi; vwall[0] = vwall[1] = vwall[2] = 0.0; if (wiggle) { double arg = omega * (update->ntimestep - time_origin) * dt; if (wallstyle == axis) { wlo = lo + amplitude - amplitude*cos(arg); whi = hi + amplitude - amplitude*cos(arg); } vwall[axis] = amplitude*omega*sin(arg); } else if (wshear) vwall[axis] = vshear; // loop over all my atoms // rsq = distance from wall // dx,dy,dz = signed distance from wall // for rotating cylinder, reset vwall based on particle position // skip atom if not close enough to wall // if wall was set to NULL, it's skipped since lo/hi are infinity // compute force and torque on atom if close enough to wall // via wall potential matched to pair potential // set shear if pair potential stores history double * const * const x = atom->x; double * const * const v = atom->v; double * const * const f = atom->f; double * const * const omega = atom->omega; double * const * const torque = atom->torque; double * const radius = atom->radius; double * const rmass = atom->rmass; const int * const mask = atom->mask; const int nlocal = atom->nlocal; shearupdate = (update->setupflag) ? 0 : 1; int i; #if defined(_OPENMP) #pragma omp parallel for private(i) default(none) firstprivate(vwall,wlo,whi) #endif for (i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { double dx,dy,dz,del1,del2,delxy,delr,rsq; + double rwall = 0.0; dx = dy = dz = 0.0; if (wallstyle == XPLANE) { del1 = x[i][0] - wlo; del2 = whi - x[i][0]; if (del1 < del2) dx = del1; else dx = -del2; } else if (wallstyle == YPLANE) { del1 = x[i][1] - wlo; del2 = whi - x[i][1]; if (del1 < del2) dy = del1; else dy = -del2; } else if (wallstyle == ZPLANE) { del1 = x[i][2] - wlo; del2 = whi - x[i][2]; if (del1 < del2) dz = del1; else dz = -del2; } else if (wallstyle == ZCYLINDER) { delxy = sqrt(x[i][0]*x[i][0] + x[i][1]*x[i][1]); delr = cylradius - delxy; - if (delr > radius[i]) dz = cylradius; - else { + if (delr > radius[i]) { + dz = cylradius; + rwall = 0.0; + } else { dx = -delr/delxy * x[i][0]; dy = -delr/delxy * x[i][1]; + rwall = (delxy < cylradius) ? -2*cylradius : 2*cylradius; if (wshear && axis != 2) { - vwall[0] = vshear * x[i][1]/delxy; - vwall[1] = -vshear * x[i][0]/delxy; + vwall[0] += vshear * x[i][1]/delxy; + vwall[1] += -vshear * x[i][0]/delxy; vwall[2] = 0.0; } } } rsq = dx*dx + dy*dy + dz*dz; if (rsq > radius[i]*radius[i]) { - if (pairstyle != HOOKE) { - shear[i][0] = 0.0; - shear[i][1] = 0.0; - shear[i][2] = 0.0; - } + if (history) + for (int j = 0; j < sheardim; j++) + shearone[i][j] = 0.0; + } else { // meff = effective mass of sphere // if I is part of rigid body, use body mass double meff = rmass[i]; if (fix_rigid && mass_rigid[i] > 0.0) meff = mass_rigid[i]; - // inovke sphere/wall interaction + // invoke sphere/wall interaction if (pairstyle == HOOKE) - hooke(rsq,dx,dy,dz,vwall,v[i],f[i],omega[i],torque[i], - radius[i],meff); + hooke(rsq,dx,dy,dz,vwall,v[i],f[i], + omega[i],torque[i],radius[i],meff); else if (pairstyle == HOOKE_HISTORY) - hooke_history(rsq,dx,dy,dz,vwall,v[i],f[i],omega[i],torque[i], - radius[i],meff,shear[i]); + hooke_history(rsq,dx,dy,dz,vwall,v[i],f[i], + omega[i],torque[i],radius[i],meff,shearone[i]); else if (pairstyle == HERTZ_HISTORY) - hertz_history(rsq,dx,dy,dz,vwall,v[i],f[i],omega[i],torque[i], - radius[i],meff,shear[i]); + hertz_history(rsq,dx,dy,dz,vwall,rwall,v[i],f[i], + omega[i],torque[i],radius[i],meff,shearone[i]); + else if (pairstyle == BONDED_HISTORY) + bonded_history(rsq,dx,dy,dz,vwall,rwall,v[i],f[i], + omega[i],torque[i],radius[i],meff,shearone[i]); } } } } /* ---------------------------------------------------------------------- */ void FixWallGranOMP::post_force_respa(int vflag, int ilevel, int iloop) { if (ilevel == nlevels_respa-1) post_force(vflag); } diff --git a/src/accelerator_kokkos.h b/src/accelerator_kokkos.h index 2a787ef11..a98263fad 100644 --- a/src/accelerator_kokkos.h +++ b/src/accelerator_kokkos.h @@ -1,98 +1,100 @@ /* -*- 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_ACCELERATOR_KOKKOS_H #define LMP_ACCELERATOR_KOKKOS_H // true interface to KOKKOS // used when KOKKOS is installed #ifdef LMP_KOKKOS #include "kokkos.h" #include "atom_kokkos.h" #include "comm_kokkos.h" #include "domain_kokkos.h" #include "neighbor_kokkos.h" #include "modify_kokkos.h" #else // dummy interface to KOKKOS // needed for compiling when KOKKOS is not installed #include "atom.h" #include "comm_brick.h" #include "domain.h" #include "neighbor.h" #include "modify.h" namespace LAMMPS_NS { class KokkosLMP { public: int kokkos_exists; int num_threads; int ngpu; int numa; KokkosLMP(class LAMMPS *, int, char **) {kokkos_exists = 0;} ~KokkosLMP() {} void accelerator(int, char **) {} int neigh_list_kokkos(int) {return 0;} int neigh_count(int) {return 0;} }; class AtomKokkos : public Atom { public: tagint **k_special; AtomKokkos(class LAMMPS *lmp) : Atom(lmp) {} ~AtomKokkos() {} + void sync(const ExecutionSpace space, unsigned int mask) {} + void modified(const ExecutionSpace space, unsigned int mask) {} }; class CommKokkos : public CommBrick { public: CommKokkos(class LAMMPS *lmp) : CommBrick(lmp) {} ~CommKokkos() {} }; class DomainKokkos : public Domain { public: DomainKokkos(class LAMMPS *lmp) : Domain(lmp) {} ~DomainKokkos() {} }; class NeighborKokkos : public Neighbor { public: NeighborKokkos(class LAMMPS *lmp) : Neighbor(lmp) {} ~NeighborKokkos() {} }; class ModifyKokkos : public Modify { public: ModifyKokkos(class LAMMPS *lmp) : Modify(lmp) {} ~ModifyKokkos() {} }; class DAT { public: typedef double tdual_xfloat_1d; typedef double tdual_FFT_SCALAR_1d; typedef int t_int_1d; typedef int tdual_int_2d; }; } #endif #endif diff --git a/src/compute_dipole_chunk.cpp b/src/compute_dipole_chunk.cpp index 4bdf23e27..74d66e7c1 100644 --- a/src/compute_dipole_chunk.cpp +++ b/src/compute_dipole_chunk.cpp @@ -1,294 +1,294 @@ /* ---------------------------------------------------------------------- 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 "string.h" +#include #include "compute_dipole_chunk.h" #include "atom.h" #include "update.h" #include "modify.h" #include "compute_chunk_atom.h" #include "domain.h" #include "memory.h" #include "error.h" #include "math_special.h" using namespace LAMMPS_NS; using namespace MathSpecial; enum { MASSCENTER, GEOMCENTER }; /* ---------------------------------------------------------------------- */ ComputeDipoleChunk::ComputeDipoleChunk(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg), idchunk(NULL), massproc(NULL), masstotal(NULL), chrgproc(NULL), chrgtotal(NULL), com(NULL), comall(NULL), dipole(NULL), dipoleall(NULL) { if ((narg != 4) && (narg != 5)) error->all(FLERR,"Illegal compute dipole/chunk command"); array_flag = 1; size_array_cols = 4; size_array_rows = 0; size_array_rows_variable = 1; extarray = 0; // ID of compute chunk/atom int n = strlen(arg[3]) + 1; idchunk = new char[n]; strcpy(idchunk,arg[3]); usecenter = MASSCENTER; if (narg == 5) { if (strncmp(arg[4],"geom",4) == 0) usecenter = GEOMCENTER; else if (strcmp(arg[4],"mass") == 0) usecenter = MASSCENTER; else error->all(FLERR,"Illegal compute dipole/chunk command"); } init(); // chunk-based data nchunk = 1; maxchunk = 0; allocate(); } /* ---------------------------------------------------------------------- */ ComputeDipoleChunk::~ComputeDipoleChunk() { delete [] idchunk; memory->destroy(massproc); memory->destroy(masstotal); memory->destroy(chrgproc); memory->destroy(chrgtotal); memory->destroy(com); memory->destroy(comall); memory->destroy(dipole); memory->destroy(dipoleall); } /* ---------------------------------------------------------------------- */ void ComputeDipoleChunk::init() { int icompute = modify->find_compute(idchunk); if (icompute < 0) error->all(FLERR,"Chunk/atom compute does not exist for " "compute dipole/chunk"); cchunk = (ComputeChunkAtom *) modify->compute[icompute]; if (strcmp(cchunk->style,"chunk/atom") != 0) error->all(FLERR,"Compute dipole/chunk does not use chunk/atom compute"); } /* ---------------------------------------------------------------------- */ void ComputeDipoleChunk::compute_array() { int i,index; double massone; double unwrap[3]; invoked_array = update->ntimestep; // compute chunk/atom assigns atoms to chunk IDs // extract ichunk index vector from compute // ichunk = 1 to Nchunk for included atoms, 0 for excluded atoms nchunk = cchunk->setup_chunks(); cchunk->compute_ichunk(); int *ichunk = cchunk->ichunk; if (nchunk > maxchunk) allocate(); size_array_rows = nchunk; // zero local per-chunk values for (int i = 0; i < nchunk; i++) { massproc[i] = chrgproc[i] = 0.0; com[i][0] = com[i][1] = com[i][2] = 0.0; dipole[i][0] = dipole[i][1] = dipole[i][2] = dipole[i][3] = 0.0; } // compute COM for each chunk double **x = atom->x; int *mask = atom->mask; int *type = atom->type; imageint *image = atom->image; double *mass = atom->mass; double *rmass = atom->rmass; double *q = atom->q; double **mu = atom->mu; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { index = ichunk[i]-1; if (index < 0) continue; if (usecenter == MASSCENTER) { if (rmass) massone = rmass[i]; else massone = mass[type[i]]; } else massone = 1.0; // usecenter == GEOMCENTER domain->unmap(x[i],image[i],unwrap); massproc[index] += massone; if (atom->q_flag) chrgproc[index] += atom->q[i]; com[index][0] += unwrap[0] * massone; com[index][1] += unwrap[1] * massone; com[index][2] += unwrap[2] * massone; } MPI_Allreduce(massproc,masstotal,nchunk,MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(chrgproc,chrgtotal,nchunk,MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(&com[0][0],&comall[0][0],3*nchunk,MPI_DOUBLE,MPI_SUM,world); for (int i = 0; i < nchunk; i++) { if (masstotal[i] > 0.0) { comall[i][0] /= masstotal[i]; comall[i][1] /= masstotal[i]; comall[i][2] /= masstotal[i]; } } // compute dipole for each chunk for (i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { index = ichunk[i]-1; if (index < 0) continue; domain->unmap(x[i],image[i],unwrap); if (atom->q_flag) { dipole[index][0] += q[i]*unwrap[0]; dipole[index][1] += q[i]*unwrap[1]; dipole[index][2] += q[i]*unwrap[2]; } if (atom->mu_flag) { dipole[index][0] += mu[i][0]; dipole[index][1] += mu[i][1]; dipole[index][2] += mu[i][2]; } } } MPI_Allreduce(&dipole[0][0],&dipoleall[0][0],4*nchunk, MPI_DOUBLE,MPI_SUM,world); for (i = 0; i < nchunk; i++) { // correct for position dependence with charged chunks dipoleall[i][0] -= chrgtotal[i]*comall[i][0]; dipoleall[i][1] -= chrgtotal[i]*comall[i][1]; dipoleall[i][2] -= chrgtotal[i]*comall[i][2]; // compute total dipole moment dipoleall[i][3] = sqrt(square(dipoleall[i][0]) + square(dipoleall[i][1]) + square(dipoleall[i][2])); } } /* ---------------------------------------------------------------------- lock methods: called by fix ave/time these methods insure vector/array size is locked for Nfreq epoch by passing lock info along to compute chunk/atom ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- increment lock counter ------------------------------------------------------------------------- */ void ComputeDipoleChunk::lock_enable() { cchunk->lockcount++; } /* ---------------------------------------------------------------------- decrement lock counter in compute chunk/atom, it if still exists ------------------------------------------------------------------------- */ void ComputeDipoleChunk::lock_disable() { int icompute = modify->find_compute(idchunk); if (icompute >= 0) { cchunk = (ComputeChunkAtom *) modify->compute[icompute]; cchunk->lockcount--; } } /* ---------------------------------------------------------------------- calculate and return # of chunks = length of vector/array ------------------------------------------------------------------------- */ int ComputeDipoleChunk::lock_length() { nchunk = cchunk->setup_chunks(); return nchunk; } /* ---------------------------------------------------------------------- set the lock from startstep to stopstep ------------------------------------------------------------------------- */ void ComputeDipoleChunk::lock(Fix *fixptr, bigint startstep, bigint stopstep) { cchunk->lock(fixptr,startstep,stopstep); } /* ---------------------------------------------------------------------- unset the lock ------------------------------------------------------------------------- */ void ComputeDipoleChunk::unlock(Fix *fixptr) { cchunk->unlock(fixptr); } /* ---------------------------------------------------------------------- free and reallocate per-chunk arrays ------------------------------------------------------------------------- */ void ComputeDipoleChunk::allocate() { memory->destroy(massproc); memory->destroy(masstotal); memory->destroy(chrgproc); memory->destroy(chrgtotal); memory->destroy(com); memory->destroy(comall); memory->destroy(dipole); memory->destroy(dipoleall); maxchunk = nchunk; memory->create(massproc,maxchunk,"dipole/chunk:massproc"); memory->create(masstotal,maxchunk,"dipole/chunk:masstotal"); memory->create(chrgproc,maxchunk,"dipole/chunk:chrgproc"); memory->create(chrgtotal,maxchunk,"dipole/chunk:chrgtotal"); memory->create(com,maxchunk,3,"dipole/chunk:com"); memory->create(comall,maxchunk,3,"dipole/chunk:comall"); memory->create(dipole,maxchunk,4,"dipole/chunk:dipole"); memory->create(dipoleall,maxchunk,4,"dipole/chunk:dipoleall"); array = dipoleall; } /* ---------------------------------------------------------------------- memory usage of local data ------------------------------------------------------------------------- */ double ComputeDipoleChunk::memory_usage() { double bytes = (bigint) maxchunk * 2 * sizeof(double); bytes += (bigint) maxchunk * 2*3 * sizeof(double); bytes += (bigint) maxchunk * 2*4 * sizeof(double); return bytes; } diff --git a/src/fix.cpp b/src/fix.cpp index 9918e40e0..fbb745022 100644 --- a/src/fix.cpp +++ b/src/fix.cpp @@ -1,308 +1,309 @@ /* ---------------------------------------------------------------------- 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 #include #include "fix.h" #include "atom.h" #include "group.h" #include "force.h" #include "comm.h" #include "atom_masks.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; using namespace FixConst; // allocate space for static class instance variable and initialize it int Fix::instance_total = 0; /* ---------------------------------------------------------------------- */ Fix::Fix(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp), id(NULL), style(NULL), eatom(NULL), vatom(NULL) { instance_me = instance_total++; // fix ID, group, and style // ID must be all alphanumeric chars or underscores int n = strlen(arg[0]) + 1; id = new char[n]; strcpy(id,arg[0]); for (int i = 0; i < n-1; i++) if (!isalnum(id[i]) && id[i] != '_') error->all(FLERR,"Fix ID must be alphanumeric or underscore characters"); igroup = group->find(arg[1]); if (igroup == -1) error->all(FLERR,"Could not find fix group ID"); groupbit = group->bitmask[igroup]; n = strlen(arg[2]) + 1; style = new char[n]; strcpy(style,arg[2]); restart_global = restart_peratom = restart_file = 0; force_reneighbor = 0; box_change_size = box_change_shape = box_change_domain = 0; thermo_energy = 0; rigid_flag = 0; peatom_flag = 0; virial_flag = 0; no_change_box = 0; time_integrate = 0; time_depend = 0; create_attribute = 0; restart_pbc = 0; wd_header = wd_section = 0; dynamic_group_allow = 0; dof_flag = 0; special_alter_flag = 0; enforce2d_flag = 0; respa_level_support = 0; respa_level = -1; scalar_flag = vector_flag = array_flag = 0; peratom_flag = local_flag = 0; size_vector_variable = size_array_rows_variable = 0; comm_forward = comm_reverse = comm_border = 0; restart_reset = 0; // reasonable defaults // however, each fix that uses these values should explicitly set them nevery = 1; global_freq = 1; // per-atom virial // set vflag_atom = 0 b/c some fixes grow vatom in grow_arrays() // which may occur outside of timestepping maxeatom = maxvatom = 0; vflag_atom = 0; // KOKKOS per-fix data masks execution_space = Host; datamask_read = ALL_MASK; datamask_modify = ALL_MASK; + kokkosable = 0; copymode = 0; } /* ---------------------------------------------------------------------- */ Fix::~Fix() { if (copymode) return; delete [] id; delete [] style; memory->destroy(eatom); memory->destroy(vatom); } /* ---------------------------------------------------------------------- process params common to all fixes here if unknown param, call modify_param specific to the fix ------------------------------------------------------------------------- */ void Fix::modify_params(int narg, char **arg) { if (narg == 0) error->all(FLERR,"Illegal fix_modify command"); int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"energy") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal fix_modify command"); if (strcmp(arg[iarg+1],"no") == 0) thermo_energy = 0; else if (strcmp(arg[iarg+1],"yes") == 0) thermo_energy = 1; else error->all(FLERR,"Illegal fix_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"respa") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal fix_modify command"); if (!respa_level_support) error->all(FLERR,"Illegal fix_modify command"); int lvl = force->inumeric(FLERR,arg[iarg+1]); if (lvl < 0) error->all(FLERR,"Illegal fix_modify command"); respa_level = lvl-1; iarg += 2; } else { int n = modify_param(narg-iarg,&arg[iarg]); if (n == 0) error->all(FLERR,"Illegal fix_modify command"); iarg += n; } } } /* ---------------------------------------------------------------------- setup for energy, virial computation see integrate::ev_set() for values of eflag (0-3) and vflag (0-6) fixes call this if use ev_tally() ------------------------------------------------------------------------- */ void Fix::ev_setup(int eflag, int vflag) { int i,n; evflag = 1; eflag_either = eflag; eflag_global = eflag % 2; eflag_atom = eflag / 2; vflag_either = vflag; vflag_global = vflag % 4; vflag_atom = vflag / 4; // reallocate per-atom arrays if necessary if (eflag_atom && atom->nlocal > maxeatom) { maxeatom = atom->nmax; memory->destroy(eatom); memory->create(eatom,maxeatom,"fix:eatom"); } if (vflag_atom && atom->nlocal > maxvatom) { maxvatom = atom->nmax; memory->destroy(vatom); memory->create(vatom,maxvatom,6,"fix:vatom"); } // zero accumulators // no global energy variable to zero (unlike pair,bond,angle,etc) // fixes tally it individually via fix_modify energy yes and compute_scalar() if (vflag_global) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag_atom) { n = atom->nlocal; for (i = 0; i < n; i++) eatom[i] = 0.0; } if (vflag_atom) { n = atom->nlocal; for (i = 0; i < n; i++) { vatom[i][0] = 0.0; vatom[i][1] = 0.0; vatom[i][2] = 0.0; vatom[i][3] = 0.0; vatom[i][4] = 0.0; vatom[i][5] = 0.0; } } } /* ---------------------------------------------------------------------- setup for virial computation see integrate::ev_set() for values of vflag (0-6) fixes call this if use v_tally() ------------------------------------------------------------------------- */ void Fix::v_setup(int vflag) { int i,n; evflag = 1; vflag_global = vflag % 4; vflag_atom = vflag / 4; // reallocate per-atom array if necessary if (vflag_atom && atom->nlocal > maxvatom) { maxvatom = atom->nmax; memory->destroy(vatom); memory->create(vatom,maxvatom,6,"fix:vatom"); } // zero accumulators if (vflag_global) for (i = 0; i < 6; i++) virial[i] = 0.0; if (vflag_atom) { n = atom->nlocal; for (i = 0; i < n; i++) { vatom[i][0] = 0.0; vatom[i][1] = 0.0; vatom[i][2] = 0.0; vatom[i][3] = 0.0; vatom[i][4] = 0.0; vatom[i][5] = 0.0; } } } /* ---------------------------------------------------------------------- tally per-atom energy and global/per-atom virial into accumulators n = # of local owned atoms involved, with local indices in list eng = total energy for the interaction involving total atoms v = total virial for the interaction involving total atoms increment per-atom energy of each atom in list by 1/total fraction v_tally tallies virial this method can be used when fix computes energy/forces in post_force() e.g. fix cmap: compute energy and virial only on owned atoms whether newton_bond is on or off other procs will tally left-over fractions for atoms they own ------------------------------------------------------------------------- */ void Fix::ev_tally(int n, int *list, double total, double eng, double *v) { if (eflag_atom) { double fraction = eng/total; for (int i = 0; i < n; i++) eatom[list[i]] += fraction; } v_tally(n,list,total,v); } /* ---------------------------------------------------------------------- tally virial into global and per-atom accumulators n = # of local owned atoms involved, with local indices in list v = total virial for the interaction involving total atoms increment global virial by n/total fraction increment per-atom virial of each atom in list by 1/total fraction this method can be used when fix computes forces in post_force() e.g. fix shake, fix rigid: compute virial only on owned atoms whether newton_bond is on or off other procs will tally left-over fractions for atoms they own ------------------------------------------------------------------------- */ void Fix::v_tally(int n, int *list, double total, double *v) { int m; if (vflag_global) { double fraction = n/total; virial[0] += fraction*v[0]; virial[1] += fraction*v[1]; virial[2] += fraction*v[2]; virial[3] += fraction*v[3]; virial[4] += fraction*v[4]; virial[5] += fraction*v[5]; } if (vflag_atom) { double fraction = 1.0/total; for (int i = 0; i < n; i++) { m = list[i]; vatom[m][0] += fraction*v[0]; vatom[m][1] += fraction*v[1]; vatom[m][2] += fraction*v[2]; vatom[m][3] += fraction*v[3]; vatom[m][4] += fraction*v[4]; vatom[m][5] += fraction*v[5]; } } } diff --git a/src/fix.h b/src/fix.h index 62cb565b1..65ababf28 100644 --- a/src/fix.h +++ b/src/fix.h @@ -1,282 +1,283 @@ /* -*- 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_FIX_H #define LMP_FIX_H #include "pointers.h" namespace LAMMPS_NS { class Fix : protected Pointers { public: static int instance_total; // # of Fix classes ever instantiated char *id,*style; int igroup,groupbit; int restart_global; // 1 if Fix saves global state, 0 if not int restart_peratom; // 1 if Fix saves peratom state, 0 if not int restart_file; // 1 if Fix writes own restart file, 0 if not int force_reneighbor; // 1 if Fix forces reneighboring, 0 if not int box_change_size; // 1 if Fix changes box size, 0 if not int box_change_shape; // 1 if Fix changes box shape, 0 if not int box_change_domain; // 1 if Fix changes proc sub-domains, 0 if not bigint next_reneighbor; // next timestep to force a reneighboring int thermo_energy; // 1 if fix_modify enabled ThEng, 0 if not int nevery; // how often to call an end_of_step fix int rigid_flag; // 1 if Fix integrates rigid bodies, 0 if not int peatom_flag; // 1 if Fix contributes per-atom eng, 0 if not int virial_flag; // 1 if Fix contributes to virial, 0 if not int no_change_box; // 1 if cannot swap ortho <-> triclinic int time_integrate; // 1 if fix performs time integration, 0 if no int time_depend; // 1 if requires continuous timestepping int create_attribute; // 1 if fix stores attributes that need // setting when a new atom is created int restart_pbc; // 1 if fix moves atoms (except integrate) // so write_restart must remap to PBC int wd_header; // # of header values fix writes to data file int wd_section; // # of sections fix writes to data file int dynamic_group_allow; // 1 if can be used with dynamic group, else 0 int dof_flag; // 1 if has dof() method (not min_dof()) int special_alter_flag; // 1 if has special_alter() meth for spec lists int enforce2d_flag; // 1 if has enforce2d method int respa_level_support; // 1 if fix supports fix_modify respa int respa_level; // which respa level to apply fix (1-Nrespa) int scalar_flag; // 0/1 if compute_scalar() function exists int vector_flag; // 0/1 if compute_vector() function exists int array_flag; // 0/1 if compute_array() function exists int size_vector; // length of global vector int size_array_rows; // rows in global array int size_array_cols; // columns in global array int size_vector_variable; // 1 if vec length is unknown in advance int size_array_rows_variable; // 1 if array rows is unknown in advance int global_freq; // frequency s/v data is available at int peratom_flag; // 0/1 if per-atom data is stored int size_peratom_cols; // 0 = vector, N = columns in peratom array int peratom_freq; // frequency per-atom data is available at int local_flag; // 0/1 if local data is stored int size_local_rows; // rows in local vector or array int size_local_cols; // 0 = vector, N = columns in local array int local_freq; // frequency local data is available at int extscalar; // 0/1 if global scalar is intensive/extensive int extvector; // 0/1/-1 if global vector is all int/ext/extlist int *extlist; // list of 0/1 int/ext for each vec component int extarray; // 0/1 if global array is intensive/extensive double *vector_atom; // computed per-atom vector double **array_atom; // computed per-atom array double *vector_local; // computed local vector double **array_local; // computed local array int comm_forward; // size of forward communication (0 if none) int comm_reverse; // size of reverse communication (0 if none) int comm_border; // size of border communication (0 if none) double virial[6]; // accumlated virial double *eatom,**vatom; // accumulated per-atom energy/virial int restart_reset; // 1 if restart just re-initialized fix // KOKKOS host/device flag and data masks + int kokkosable; // 1 if Kokkos fix ExecutionSpace execution_space; unsigned int datamask_read,datamask_modify; Fix(class LAMMPS *, int, char **); virtual ~Fix(); void modify_params(int, char **); virtual int setmask() = 0; virtual void post_constructor() {} virtual void init() {} virtual void init_list(int, class NeighList *) {} virtual void setup(int) {} virtual void setup_pre_exchange() {} virtual void setup_pre_neighbor() {} virtual void setup_pre_force(int) {} virtual void min_setup(int) {} virtual void initial_integrate(int) {} virtual void post_integrate() {} virtual void pre_exchange() {} virtual void pre_neighbor() {} virtual void pre_force(int) {} virtual void pre_reverse(int,int) {} virtual void post_force(int) {} virtual void final_integrate() {} virtual void end_of_step() {} virtual void post_run() {} virtual void write_restart(FILE *) {} virtual void write_restart_file(char *) {} virtual void restart(char *) {} virtual void grow_arrays(int) {} virtual void copy_arrays(int, int, int) {} virtual void set_arrays(int) {} virtual void update_arrays(int, int) {} virtual void set_molecule(int, tagint, int, double *, double *, double *) {} virtual void clear_bonus() {} virtual int pack_border(int, int *, double *) {return 0;} virtual int unpack_border(int, int, double *) {return 0;} virtual int pack_exchange(int, double *) {return 0;} virtual int unpack_exchange(int, double *) {return 0;} virtual int pack_restart(int, double *) {return 0;} virtual void unpack_restart(int, int) {} virtual int size_restart(int) {return 0;} virtual int maxsize_restart() {return 0;} virtual void setup_pre_force_respa(int, int) {} virtual void initial_integrate_respa(int, int, int) {} virtual void post_integrate_respa(int, int) {} virtual void pre_force_respa(int, int, int) {} virtual void post_force_respa(int, int, int) {} virtual void final_integrate_respa(int, int) {} virtual void min_setup_pre_exchange() {} virtual void min_setup_pre_neighbor() {} virtual void min_setup_pre_force(int) {} virtual void min_pre_exchange() {} virtual void min_pre_neighbor() {} virtual void min_pre_force(int) {} virtual void min_post_force(int) {} virtual double min_energy(double *) {return 0.0;} virtual void min_store() {} virtual void min_clearstore() {} virtual void min_pushstore() {} virtual void min_popstore() {} virtual int min_reset_ref() {return 0;} virtual void min_step(double, double *) {} virtual double max_alpha(double *) {return 0.0;} virtual int min_dof() {return 0;} virtual int pack_forward_comm(int, int *, double *, int, int *) {return 0;} virtual void unpack_forward_comm(int, int, double *) {} virtual int pack_reverse_comm_size(int, int) {return 0;} virtual int pack_reverse_comm(int, int, double *) {return 0;} virtual void unpack_reverse_comm(int, int *, double *) {} virtual double compute_scalar() {return 0.0;} virtual double compute_vector(int) {return 0.0;} virtual double compute_array(int,int) {return 0.0;} virtual int dof(int) {return 0;} virtual void deform(int) {} virtual void reset_target(double) {} virtual void reset_dt() {} virtual void enforce2d() {} virtual void read_data_header(char *) {} virtual void read_data_section(char *, int, char *, tagint) {} virtual bigint read_data_skip_lines(char *) {return 0;} virtual void write_data_header(FILE *, int) {} virtual void write_data_section_size(int, int &, int &) {} virtual void write_data_section_pack(int, double **) {} virtual void write_data_section_keyword(int, FILE *) {} virtual void write_data_section(int, FILE *, int, double **, int) {} virtual void zero_momentum() {} virtual void zero_rotation() {} virtual void rebuild_special() {} virtual int image(int *&, double **&) {return 0;} virtual int modify_param(int, char **) {return 0;} virtual void *extract(const char *, int &) {return NULL;} virtual double memory_usage() {return 0.0;} protected: int instance_me; // which Fix class instantiation I am int evflag; int eflag_either,eflag_global,eflag_atom; int vflag_either,vflag_global,vflag_atom; int maxeatom,maxvatom; int copymode; // if set, do not deallocate during destruction // required when classes are used as functors by Kokkos void ev_setup(int, int); void ev_tally(int, int *, double, double, double *); void v_setup(int); void v_tally(int, int *, double, double *); // union data struct for packing 32-bit and 64-bit ints into double bufs // see atom_vec.h for documentation union ubuf { double d; int64_t i; ubuf(double arg) : d(arg) {} ubuf(int64_t arg) : i(arg) {} ubuf(int arg) : i(arg) {} }; }; namespace FixConst { static const int INITIAL_INTEGRATE = 1<<0; static const int POST_INTEGRATE = 1<<1; static const int PRE_EXCHANGE = 1<<2; static const int PRE_NEIGHBOR = 1<<3; static const int PRE_FORCE = 1<<4; static const int POST_FORCE = 1<<5; static const int FINAL_INTEGRATE = 1<<6; static const int END_OF_STEP = 1<<7; static const int THERMO_ENERGY = 1<<8; static const int INITIAL_INTEGRATE_RESPA = 1<<9; static const int POST_INTEGRATE_RESPA = 1<<10; static const int PRE_FORCE_RESPA = 1<<11; static const int POST_FORCE_RESPA = 1<<12; static const int FINAL_INTEGRATE_RESPA = 1<<13; static const int MIN_PRE_EXCHANGE = 1<<14; static const int MIN_PRE_NEIGHBOR = 1<<15; static const int MIN_PRE_FORCE = 1<<16; static const int MIN_POST_FORCE = 1<<17; static const int MIN_ENERGY = 1<<18; static const int POST_RUN = 1<<19; static const int PRE_REVERSE = 1<<20; static const int FIX_CONST_LAST = 1<<21; } } #endif /* ERROR/WARNING messages: E: Fix ID must be alphanumeric or underscore characters Self-explanatory. E: Could not find fix group ID A group ID used in the fix command does not exist. E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. */ diff --git a/src/region.cpp b/src/region.cpp index ea0b6f1bc..08505d1ba 100644 --- a/src/region.cpp +++ b/src/region.cpp @@ -1,403 +1,573 @@ /* ---------------------------------------------------------------------- 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 #include #include #include "region.h" #include "update.h" #include "domain.h" #include "lattice.h" #include "input.h" #include "variable.h" +#include "math_extra.h" #include "error.h" #include "force.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ Region::Region(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) { int n = strlen(arg[0]) + 1; id = new char[n]; strcpy(id,arg[0]); n = strlen(arg[1]) + 1; style = new char[n]; strcpy(style,arg[1]); varshape = 0; xstr = ystr = zstr = tstr = NULL; dx = dy = dz = 0.0; + // used by set_velocity() even if no rotation specified + + point[0] = point[1] = point[2] = 0.0; + + size_restart = 5; + reset_vel(); copymode = 0; + list = NULL; + nregion = 1; } /* ---------------------------------------------------------------------- */ Region::~Region() { if (copymode) return; delete [] id; delete [] style; delete [] xstr; delete [] ystr; delete [] zstr; delete [] tstr; } /* ---------------------------------------------------------------------- */ void Region::init() { if (xstr) { xvar = input->variable->find(xstr); if (xvar < 0) error->all(FLERR,"Variable name for region does not exist"); if (!input->variable->equalstyle(xvar)) error->all(FLERR,"Variable for region is invalid style"); } if (ystr) { yvar = input->variable->find(ystr); if (yvar < 0) error->all(FLERR,"Variable name for region does not exist"); if (!input->variable->equalstyle(yvar)) error->all(FLERR,"Variable for region is not equal style"); } if (zstr) { zvar = input->variable->find(zstr); if (zvar < 0) error->all(FLERR,"Variable name for region does not exist"); if (!input->variable->equalstyle(zvar)) error->all(FLERR,"Variable for region is not equal style"); } if (tstr) { tvar = input->variable->find(tstr); if (tvar < 0) error->all(FLERR,"Variable name for region does not exist"); if (!input->variable->equalstyle(tvar)) error->all(FLERR,"Variable for region is not equal style"); } + vel_timestep = -1; } /* ---------------------------------------------------------------------- return 1 if region is dynamic (moves/rotates) or has variable shape else return 0 if static ------------------------------------------------------------------------- */ int Region::dynamic_check() { if (dynamic || varshape) return 1; return 0; } /* ---------------------------------------------------------------------- called before looping over atoms with match() or surface() this insures any variables used by region are invoked once per timestep - also insures variables are invoked by all procs even those w/out atoms + also insures variables are invoked by all procs even those w/out atoms necessary if equal-style variable invokes global operation - with MPI_Allreduce, e.g. xcm() or count() + with MPI_Allreduce, e.g. xcm() or count() ------------------------------------------------------------------------- */ void Region::prematch() { if (varshape) shape_update(); if (dynamic) pretransform(); } /* ---------------------------------------------------------------------- determine if point x,y,z is a match to region volume XOR computes 0 if 2 args are the same, 1 if different note that inside() returns 1 for points on surface of region thus point on surface of exterior region will not match if region has variable shape, invoke shape_update() once per timestep if region is dynamic, apply inverse transform to x,y,z unmove first, then unrotate, so don't have to change rotation point caller is responsible for wrapping this call with modify->clearstep_compute() and modify->addstep_compute() if needed ------------------------------------------------------------------------- */ int Region::match(double x, double y, double z) { if (dynamic) inverse_transform(x,y,z); + if (openflag) return 1; return !(inside(x,y,z) ^ interior); } /* ---------------------------------------------------------------------- generate error if Kokkos function defaults to base class ------------------------------------------------------------------------- */ void Region::match_all_kokkos(int, DAT::t_int_1d) { error->all(FLERR,"Can only use Kokkos supported regions with Kokkos package"); } /* ---------------------------------------------------------------------- generate list of contact points for interior or exterior regions if region has variable shape, invoke shape_update() once per timestep if region is dynamic: before: inverse transform x,y,z (unmove, then unrotate) after: forward transform contact point xs,yx,zs (rotate, then move), then reset contact delx,dely,delz based on new contact point no need to do this if no rotation since delxyz doesn't change caller is responsible for wrapping this call with modify->clearstep_compute() and modify->addstep_compute() if needed ------------------------------------------------------------------------- */ int Region::surface(double x, double y, double z, double cutoff) { int ncontact; double xs,ys,zs; double xnear[3],xorig[3]; if (dynamic) { xorig[0] = x; xorig[1] = y; xorig[2] = z; inverse_transform(x,y,z); } xnear[0] = x; xnear[1] = y; xnear[2] = z; - if (interior) ncontact = surface_interior(xnear,cutoff); - else ncontact = surface_exterior(xnear,cutoff); + if (!openflag) { + if (interior) ncontact = surface_interior(xnear,cutoff); + else ncontact = surface_exterior(xnear,cutoff); + } + else{ + // one of surface_int/ext() will return 0 + // so no need to worry about offset of contact indices + ncontact = surface_exterior(xnear,cutoff) + surface_interior(xnear,cutoff); + } if (rotateflag && ncontact) { for (int i = 0; i < ncontact; i++) { xs = xnear[0] - contact[i].delx; ys = xnear[1] - contact[i].dely; zs = xnear[2] - contact[i].delz; forward_transform(xs,ys,zs); contact[i].delx = xorig[0] - xs; contact[i].dely = xorig[1] - ys; contact[i].delz = xorig[2] - zs; } } return ncontact; } /* ---------------------------------------------------------------------- add a single contact at Nth location in contact array x = particle position xp,yp,zp = region surface point ------------------------------------------------------------------------- */ void Region::add_contact(int n, double *x, double xp, double yp, double zp) { double delx = x[0] - xp; double dely = x[1] - yp; double delz = x[2] - zp; contact[n].r = sqrt(delx*delx + dely*dely + delz*delz); + contact[n].radius = 0; contact[n].delx = delx; contact[n].dely = dely; contact[n].delz = delz; } /* ---------------------------------------------------------------------- pre-compute dx,dy,dz and theta for a moving/rotating region called once for the region before per-atom loop, via prematch() ------------------------------------------------------------------------- */ void Region::pretransform() { if (moveflag) { if (xstr) dx = input->variable->compute_equal(xvar); if (ystr) dy = input->variable->compute_equal(yvar); if (zstr) dz = input->variable->compute_equal(zvar); } if (rotateflag) theta = input->variable->compute_equal(tvar); } /* ---------------------------------------------------------------------- transform a point x,y,z in region space to moved space rotate first (around original P), then displace ------------------------------------------------------------------------- */ void Region::forward_transform(double &x, double &y, double &z) { if (rotateflag) rotate(x,y,z,theta); if (moveflag) { x += dx; y += dy; z += dz; } } /* ---------------------------------------------------------------------- transform a point x,y,z in moved space back to region space undisplace first, then unrotate (around original P) ------------------------------------------------------------------------- */ void Region::inverse_transform(double &x, double &y, double &z) { if (moveflag) { x -= dx; y -= dy; z -= dz; } if (rotateflag) rotate(x,y,z,-theta); } /* ---------------------------------------------------------------------- rotate x,y,z by angle via right-hand rule around point and runit normal sign of angle determines whether rotating forward/backward in time return updated x,y,z R = vector axis of rotation P = point = point to rotate around R0 = runit = unit vector for R X0 = x,y,z = initial coord of atom D = X0 - P = vector from P to X0 C = (D dot R0) R0 = projection of D onto R, i.e. Dparallel A = D - C = vector from R line to X0, i.e. Dperp B = R0 cross A = vector perp to A in plane of rotation, same len as A A,B define plane of circular rotation around R line new x,y,z = P + C + A cos(angle) + B sin(angle) ------------------------------------------------------------------------- */ void Region::rotate(double &x, double &y, double &z, double angle) { double a[3],b[3],c[3],d[3],disp[3]; double sine = sin(angle); double cosine = cos(angle); d[0] = x - point[0]; d[1] = y - point[1]; d[2] = z - point[2]; double x0dotr = d[0]*runit[0] + d[1]*runit[1] + d[2]*runit[2]; c[0] = x0dotr * runit[0]; c[1] = x0dotr * runit[1]; c[2] = x0dotr * runit[2]; a[0] = d[0] - c[0]; a[1] = d[1] - c[1]; a[2] = d[2] - c[2]; b[0] = runit[1]*a[2] - runit[2]*a[1]; b[1] = runit[2]*a[0] - runit[0]*a[2]; b[2] = runit[0]*a[1] - runit[1]*a[0]; disp[0] = a[0]*cosine + b[0]*sine; disp[1] = a[1]*cosine + b[1]*sine; disp[2] = a[2]*cosine + b[2]*sine; x = point[0] + c[0] + disp[0]; y = point[1] + c[1] + disp[1]; z = point[2] + c[2] + disp[2]; } /* ---------------------------------------------------------------------- parse optional parameters at end of region input line ------------------------------------------------------------------------- */ void Region::options(int narg, char **arg) { if (narg < 0) error->all(FLERR,"Illegal region command"); // option defaults interior = 1; scaleflag = 1; moveflag = rotateflag = 0; + openflag = 0; + for (int i = 0; i < 6; i++) open_faces[i] = 0; + int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"units") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal region command"); if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; else error->all(FLERR,"Illegal region command"); iarg += 2; } else if (strcmp(arg[iarg],"side") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal region command"); if (strcmp(arg[iarg+1],"in") == 0) interior = 1; else if (strcmp(arg[iarg+1],"out") == 0) interior = 0; else error->all(FLERR,"Illegal region command"); iarg += 2; } else if (strcmp(arg[iarg],"move") == 0) { if (iarg+4 > narg) error->all(FLERR,"Illegal region command"); if (strcmp(arg[iarg+1],"NULL") != 0) { if (strstr(arg[iarg+1],"v_") != arg[iarg+1]) error->all(FLERR,"Illegal region command"); int n = strlen(&arg[iarg+1][2]) + 1; xstr = new char[n]; strcpy(xstr,&arg[iarg+1][2]); } if (strcmp(arg[iarg+2],"NULL") != 0) { if (strstr(arg[iarg+2],"v_") != arg[iarg+2]) error->all(FLERR,"Illegal region command"); int n = strlen(&arg[iarg+2][2]) + 1; ystr = new char[n]; strcpy(ystr,&arg[iarg+2][2]); } if (strcmp(arg[iarg+3],"NULL") != 0) { if (strstr(arg[iarg+3],"v_") != arg[iarg+3]) error->all(FLERR,"Illegal region command"); int n = strlen(&arg[iarg+3][2]) + 1; zstr = new char[n]; strcpy(zstr,&arg[iarg+3][2]); } moveflag = 1; iarg += 4; } else if (strcmp(arg[iarg],"rotate") == 0) { if (iarg+8 > narg) error->all(FLERR,"Illegal region command"); if (strstr(arg[iarg+1],"v_") != arg[iarg+1]) error->all(FLERR,"Illegal region command"); int n = strlen(&arg[iarg+1][2]) + 1; tstr = new char[n]; strcpy(tstr,&arg[iarg+1][2]); point[0] = force->numeric(FLERR,arg[iarg+2]); point[1] = force->numeric(FLERR,arg[iarg+3]); point[2] = force->numeric(FLERR,arg[iarg+4]); axis[0] = force->numeric(FLERR,arg[iarg+5]); axis[1] = force->numeric(FLERR,arg[iarg+6]); axis[2] = force->numeric(FLERR,arg[iarg+7]); rotateflag = 1; iarg += 8; - } else error->all(FLERR,"Illegal region command"); + + } else if (strcmp(arg[iarg],"open") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal region command"); + int iface = force->inumeric(FLERR,arg[iarg+1]); + if (iface < 1 || iface > 6) error->all(FLERR,"Illegal region command"); + // additional checks on valid face index are done by region classes + open_faces[iface-1] = 1; + openflag = 1; + iarg += 2; + } + else error->all(FLERR,"Illegal region command"); } + // error check if ((moveflag || rotateflag) && (strcmp(style,"union") == 0 || strcmp(style,"intersect") == 0)) error->all(FLERR,"Region union or intersect cannot be dynamic"); // setup scaling if (scaleflag) { xscale = domain->lattice->xlattice; yscale = domain->lattice->ylattice; zscale = domain->lattice->zlattice; } else xscale = yscale = zscale = 1.0; if (rotateflag) { point[0] *= xscale; point[1] *= yscale; point[2] *= zscale; } // runit = unit vector along rotation axis if (rotateflag) { double len = sqrt(axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]); if (len == 0.0) error->all(FLERR,"Region cannot have 0 length rotation vector"); runit[0] = axis[0]/len; runit[1] = axis[1]/len; runit[2] = axis[2]/len; } if (moveflag || rotateflag) dynamic = 1; else dynamic = 0; } + +/* ---------------------------------------------------------------------- + find nearest point to C on line segment A,B and return it as D + project (C-A) onto (B-A) + t = length of that projection, normalized by length of (B-A) + t <= 0, C is closest to A + t >= 1, C is closest to B + else closest point is between A and B +------------------------------------------------------------------------- */ + +void Region::point_on_line_segment(double *a, double *b, + double *c, double *d) +{ + double ba[3],ca[3]; + + MathExtra::sub3(b,a,ba); + MathExtra::sub3(c,a,ca); + double t = MathExtra::dot3(ca,ba) / MathExtra::dot3(ba,ba); + if (t <= 0.0) { + d[0] = a[0]; + d[1] = a[1]; + d[2] = a[2]; + } else if (t >= 1.0) { + d[0] = b[0]; + d[1] = b[1]; + d[2] = b[2]; + } else { + d[0] = a[0] + t*ba[0]; + d[1] = a[1] + t*ba[1]; + d[2] = a[2] + t*ba[2]; + } +} + +/* ---------------------------------------------------------------------- + infer translational and angular velocity of region + necessary b/c motion variables are for displacement & theta + there is no analytic formula for v & omega + prev[4] contains values of dx,dy,dz,theta at previous step + used for difference, then updated to current step values + dt is time elapsed since previous step + rpoint = point updated by current displacement + called by fix wall/gran/region every timestep +------------------------------------------------------------------------- */ + +void Region::set_velocity() +{ + if (vel_timestep == update->ntimestep) return; + vel_timestep = update->ntimestep; + if (moveflag) { + if (update->ntimestep > 0) { + v[0] = (dx - prev[0])/update->dt; + v[1] = (dy - prev[1])/update->dt; + v[2] = (dz - prev[2])/update->dt; + } + else v[0] = v[1] = v[2] = 0.0; + prev[0] = dx; + prev[1] = dy; + prev[2] = dz; + } + + if (rotateflag) { + rpoint[0] = point[0] + dx; + rpoint[1] = point[1] + dy; + rpoint[2] = point[2] + dz; + if (update->ntimestep > 0) { + double angvel = (theta-prev[3]) / update->dt; + omega[0] = angvel*axis[0]; + omega[1] = angvel*axis[1]; + omega[2] = angvel*axis[2]; + } + else omega[0] = omega[1] = omega[2] = 0.0; + prev[3] = theta; + } + + if (varshape){ + set_velocity_shape(); + } +} + +/* ---------------------------------------------------------------------- + compute velocity of wall for given contact + since contacts only store delx/y/z, need to pass particle coords + to compute contact point + called by fix/wall/gran/region every contact every timestep +------------------------------------------------------------------------- */ + +void Region::velocity_contact(double *vwall, double *x, int ic) +{ + Contact c = contact[ic]; + double xc[3]; + xc[0] = x[0] - contact[ic].delx; + xc[1] = x[1] - contact[ic].dely; + xc[2] = x[2] - contact[ic].delz; + + vwall[0] = v[0] + omega[1]*(xc[2] - rpoint[2]) - omega[2]*(xc[1] - rpoint[1]); + vwall[1] = v[1] + omega[2]*(xc[0] - rpoint[0]) - omega[0]*(xc[2] - rpoint[2]); + vwall[2] = v[2] + omega[0]*(xc[1] - rpoint[1]) - omega[1]*(xc[0] - rpoint[0]); + + if (varshape && contact[ic].varflag) velocity_contact_shape(vwall,xc); +} + +/* ---------------------------------------------------------------------- + region writes its current position/angle + needed by fix/wall/gran/region to compute velocity by differencing scheme +------------------------------------------------------------------------- */ + +void Region::write_restart(FILE *fp) +{ + fwrite(prev, sizeof(double), size_restart, fp); +} + +/* ---------------------------------------------------------------------- + region reads its previous position/angle + needed by fix/wall/gran/region to compute velocity by differencing scheme +------------------------------------------------------------------------- */ + +int Region::restart(char *buf, int n) +{ + char *rlist = new char[size_restart*sizeof(double)]; + for (int i = 0; i < size_restart*sizeof(double); i++) + rlist[i] = buf[n++]; + for (int i = 0; i < size_restart; i++) { + prev[i] = ((double *)rlist)[i]; + } + delete [] rlist; + return n; +} + +/* ---------------------------------------------------------------------- + set prev vector to zero +------------------------------------------------------------------------- */ + +void Region::reset_vel() +{ + for (int i = 0; i < size_restart; i++) + prev[i] = 0; +} diff --git a/src/region.h b/src/region.h index d330a9bf3..4b53c4e23 100644 --- a/src/region.h +++ b/src/region.h @@ -1,121 +1,151 @@ /* -*- 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_REGION_H #define LMP_REGION_H #include "pointers.h" #include "accelerator_kokkos.h" namespace LAMMPS_NS { class Region : protected Pointers { public: char *id,*style; int interior; // 1 for interior, 0 for exterior int scaleflag; // 1 for lattice, 0 for box double xscale,yscale,zscale; // scale factors for box/lattice units double extent_xlo,extent_xhi; // bounding box on region double extent_ylo,extent_yhi; double extent_zlo,extent_zhi; int bboxflag; // 1 if bounding box is computable int varshape; // 1 if region shape changes over time int dynamic; // 1 if position/orient changes over time + int moveflag,rotateflag; // 1 if position/orientation changes + int openflag; // 1 if any face is open + int open_faces[6]; // flags for which faces are open int copymode; // 1 if copy of original class - // contact = particle near region surface + // contact = particle near region surface (for soft interactions) + // touch = particle touching region surface (for granular interactions) struct Contact { double r; // distance between particle & surf, r > 0.0 double delx,dely,delz; // vector from surface pt to particle + double radius; // curvature of region at contact point + int iwall; // unique id of wall for storing shear history + int varflag; // 1 if wall can be variable-controlled }; Contact *contact; // list of contacts int cmax; // max # of contacts possible with region + int tmax; // max # of touching contacts possible + + // motion attributes of region + // public so can be accessed by other classes + + double dx,dy,dz,theta; // current displacement and orientation + double v[3]; // translational velocity + double rpoint[3]; // current origin of rotation axis + double omega[3]; // angular velocity + double rprev; // speed of time-dependent radius, if applicable + double xcenter[3]; // translated/rotated center of cylinder/sphere + // only used with varshape + double prev[5]; // stores displacement (X3), angle and if + // necessary, region variable size (e.g. radius) + // at previous time step + int vel_timestep; // store timestep at which set_velocity was called + // prevents multiple fix/wall/gran/region calls + int nregion; // For union and intersect + int size_restart; + int *list; Region(class LAMMPS *, int, char **); virtual ~Region(); virtual void init(); int dynamic_check(); // called by other classes to check point versus region void prematch(); int match(double, double, double); int surface(double, double, double, double); + virtual void set_velocity(); + void velocity_contact(double *, double *, int); + virtual void write_restart(FILE *); + virtual int restart(char *, int); + virtual void reset_vel(); + // implemented by each region, not called by other classes virtual int inside(double, double, double) = 0; virtual int surface_interior(double *, double) = 0; virtual int surface_exterior(double *, double) = 0; virtual void shape_update() {} virtual void pretransform(); + virtual void set_velocity_shape() {} + virtual void velocity_contact_shape(double*, double*) {} // Kokkos function, implemented by each Kokkos region virtual void match_all_kokkos(int, DAT::t_int_1d); protected: void add_contact(int, double *, double, double, double); void options(int, char **); + void point_on_line_segment(double *, double *, double *, double *); + void forward_transform(double &, double &, double &); - int moveflag,rotateflag; // 1 if position/orientation changes - - double point[3],axis[3],runit[3]; + private: char *xstr,*ystr,*zstr,*tstr; int xvar,yvar,zvar,tvar; - double dx,dy,dz,theta; + double axis[3],point[3],runit[3]; - void forward_transform(double &, double &, double &); void inverse_transform(double &, double &, double &); void rotate(double &, double &, double &, double); }; } #endif /* ERROR/WARNING messages: E: Variable name for region does not exist Self-explanatory. E: Variable for region is invalid style Only equal-style variables can be used. E: Variable for region is not equal style Self-explanatory. -E: Can only use Kokkos supported regions with Kokkos package - -Self-explanatory. - E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. E: Region union or intersect cannot be dynamic The sub-regions can be dynamic, but not the combined region. E: Region cannot have 0 length rotation vector Self-explanatory. */ diff --git a/src/region_block.cpp b/src/region_block.cpp index f866903f3..f48aa5af8 100644 --- a/src/region_block.cpp +++ b/src/region_block.cpp @@ -1,228 +1,436 @@ /* ---------------------------------------------------------------------- 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 #include #include "region_block.h" +#include "force.h" #include "domain.h" +#include "math_extra.h" #include "error.h" -#include "force.h" using namespace LAMMPS_NS; #define BIG 1.0e20 /* ---------------------------------------------------------------------- */ RegBlock::RegBlock(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) { options(narg-8,&arg[8]); if (strcmp(arg[2],"INF") == 0 || strcmp(arg[2],"EDGE") == 0) { if (domain->box_exist == 0) error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[2],"INF") == 0) xlo = -BIG; else if (domain->triclinic == 0) xlo = domain->boxlo[0]; else xlo = domain->boxlo_bound[0]; } else xlo = xscale*force->numeric(FLERR,arg[2]); if (strcmp(arg[3],"INF") == 0 || strcmp(arg[3],"EDGE") == 0) { if (domain->box_exist == 0) error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[3],"INF") == 0) xhi = BIG; else if (domain->triclinic == 0) xhi = domain->boxhi[0]; else xhi = domain->boxhi_bound[0]; } else xhi = xscale*force->numeric(FLERR,arg[3]); if (strcmp(arg[4],"INF") == 0 || strcmp(arg[4],"EDGE") == 0) { if (domain->box_exist == 0) error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[4],"INF") == 0) ylo = -BIG; else if (domain->triclinic == 0) ylo = domain->boxlo[1]; else ylo = domain->boxlo_bound[1]; } else ylo = yscale*force->numeric(FLERR,arg[4]); if (strcmp(arg[5],"INF") == 0 || strcmp(arg[5],"EDGE") == 0) { if (domain->box_exist == 0) error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[5],"INF") == 0) yhi = BIG; else if (domain->triclinic == 0) yhi = domain->boxhi[1]; else yhi = domain->boxhi_bound[1]; } else yhi = yscale*force->numeric(FLERR,arg[5]); if (strcmp(arg[6],"INF") == 0 || strcmp(arg[6],"EDGE") == 0) { if (domain->box_exist == 0) error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[6],"INF") == 0) zlo = -BIG; else if (domain->triclinic == 0) zlo = domain->boxlo[2]; else zlo = domain->boxlo_bound[2]; } else zlo = zscale*force->numeric(FLERR,arg[6]); if (strcmp(arg[7],"INF") == 0 || strcmp(arg[7],"EDGE") == 0) { if (domain->box_exist == 0) error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[7],"INF") == 0) zhi = BIG; else if (domain->triclinic == 0) zhi = domain->boxhi[2]; else zhi = domain->boxhi_bound[2]; } else zhi = zscale*force->numeric(FLERR,arg[7]); // error check if (xlo > xhi || ylo > yhi || zlo > zhi) error->all(FLERR,"Illegal region block command"); // extent of block if (interior) { bboxflag = 1; extent_xlo = xlo; extent_xhi = xhi; extent_ylo = ylo; extent_yhi = yhi; extent_zlo = zlo; extent_zhi = zhi; } else bboxflag = 0; // particle could be close to all 6 planes + // particle can only touch 3 planes cmax = 6; contact = new Contact[cmax]; + if (interior) tmax = 3; + else tmax = 1; + + // open face data structs + + face[0][0] = -1.0; + face[0][1] = 0.0; + face[0][2] = 0.0; + face[1][0] = 1.0; + face[1][1] = 0.0; + face[1][2] = 0.0; + face[2][0] = 0.0; + face[2][1] = -1.0; + face[2][2] = 0.0; + face[3][0] = 0.0; + face[3][1] = 1.0; + face[3][2] = 0.0; + face[4][0] = 0.0; + face[4][1] = 0.0; + face[4][2] = -1.0; + face[5][0] = 0.0; + face[5][1] = 0.0; + face[5][2] = 1.0; + + // face[0] + + corners[0][0][0] = xlo; + corners[0][0][1] = ylo; + corners[0][0][2] = zlo; + corners[0][1][0] = xlo; + corners[0][1][1] = ylo; + corners[0][1][2] = zhi; + corners[0][2][0] = xlo; + corners[0][2][1] = yhi; + corners[0][2][2] = zhi; + corners[0][3][0] = xlo; + corners[0][3][1] = yhi; + corners[0][3][2] = zlo; + + // face[1] + + corners[1][0][0] = xhi; + corners[1][0][1] = ylo; + corners[1][0][2] = zlo; + corners[1][1][0] = xhi; + corners[1][1][1] = ylo; + corners[1][1][2] = zhi; + corners[1][2][0] = xhi; + corners[1][2][1] = yhi; + corners[1][2][2] = zhi; + corners[1][3][0] = xhi; + corners[1][3][1] = yhi; + corners[1][3][2] = zlo; + + // face[2] + + MathExtra::copy3(corners[2][0],corners[0][0]); + MathExtra::copy3(corners[2][1],corners[1][0]); + MathExtra::copy3(corners[2][2],corners[1][1]); + MathExtra::copy3(corners[2][3],corners[0][1]); + + // face[3] + + MathExtra::copy3(corners[3][0],corners[0][3]); + MathExtra::copy3(corners[3][1],corners[0][2]); + MathExtra::copy3(corners[3][2],corners[1][2]); + MathExtra::copy3(corners[3][3],corners[1][3]); + + // face[4] + + MathExtra::copy3(corners[4][0],corners[0][0]); + MathExtra::copy3(corners[4][1],corners[0][3]); + MathExtra::copy3(corners[4][2],corners[1][3]); + MathExtra::copy3(corners[4][3],corners[1][0]); + + // face[5] + + MathExtra::copy3(corners[5][0],corners[0][1]); + MathExtra::copy3(corners[5][1],corners[1][1]); + MathExtra::copy3(corners[5][2],corners[1][2]); + MathExtra::copy3(corners[5][3],corners[0][2]); } /* ---------------------------------------------------------------------- */ RegBlock::~RegBlock() { if (copymode) return; delete [] contact; } /* ---------------------------------------------------------------------- inside = 1 if x,y,z is inside or on surface inside = 0 if x,y,z is outside and not on surface ------------------------------------------------------------------------- */ int RegBlock::inside(double x, double y, double z) { if (x >= xlo && x <= xhi && y >= ylo && y <= yhi && z >= zlo && z <= zhi) return 1; return 0; } /* ---------------------------------------------------------------------- contact if 0 <= x < cutoff from one or more inner surfaces of block can be one contact for each of 6 faces no contact if outside (possible if called from union/intersect) delxyz = vector from nearest point on block to x ------------------------------------------------------------------------- */ int RegBlock::surface_interior(double *x, double cutoff) { double delta; // x is exterior to block if (x[0] < xlo || x[0] > xhi || x[1] < ylo || x[1] > yhi || x[2] < zlo || x[2] > zhi) return 0; // x is interior to block or on its surface int n = 0; delta = x[0] - xlo; - if (delta < cutoff) { + if (delta < cutoff && !open_faces[0]) { contact[n].r = delta; contact[n].delx = delta; contact[n].dely = contact[n].delz = 0.0; + contact[n].radius = 0; + contact[n].iwall = 0; n++; } delta = xhi - x[0]; - if (delta < cutoff) { + if (delta < cutoff && !open_faces[1]) { contact[n].r = delta; contact[n].delx = -delta; contact[n].dely = contact[n].delz = 0.0; + contact[n].radius = 0; + contact[n].iwall = 1; n++; } delta = x[1] - ylo; - if (delta < cutoff) { + if (delta < cutoff && !open_faces[2]) { contact[n].r = delta; contact[n].dely = delta; contact[n].delx = contact[n].delz = 0.0; + contact[n].radius = 0; + contact[n].iwall = 2; n++; } delta = yhi - x[1]; - if (delta < cutoff) { + if (delta < cutoff && !open_faces[3]) { contact[n].r = delta; contact[n].dely = -delta; contact[n].delx = contact[n].delz = 0.0; + contact[n].radius = 0; + contact[n].iwall = 3; n++; } delta = x[2] - zlo; - if (delta < cutoff) { + if (delta < cutoff && !open_faces[4]) { contact[n].r = delta; contact[n].delz = delta; contact[n].delx = contact[n].dely = 0.0; + contact[n].radius = 0; + contact[n].iwall = 4; n++; } delta = zhi - x[2]; - if (delta < cutoff) { + if (delta < cutoff && !open_faces[5]) { contact[n].r = delta; contact[n].delz = -delta; contact[n].delx = contact[n].dely = 0.0; + contact[n].radius = 0; + contact[n].iwall = 5; n++; } return n; } /* ---------------------------------------------------------------------- one contact if 0 <= x < cutoff from outer surface of block no contact if inside (possible if called from union/intersect) delxyz = vector from nearest point on block to x ------------------------------------------------------------------------- */ int RegBlock::surface_exterior(double *x, double cutoff) { double xp,yp,zp; + double xc,yc,zc,dist,mindist; // x is far enough from block that there is no contact // x is interior to block if (x[0] <= xlo-cutoff || x[0] >= xhi+cutoff || x[1] <= ylo-cutoff || x[1] >= yhi+cutoff || x[2] <= zlo-cutoff || x[2] >= zhi+cutoff) return 0; if (x[0] > xlo && x[0] < xhi && x[1] > ylo && x[1] < yhi && x[2] > zlo && x[2] < zhi) return 0; // x is exterior to block or on its surface // xp,yp,zp = point on surface of block that x is closest to // could be edge or corner pt of block // do not add contact point if r >= cutoff - if (x[0] < xlo) xp = xlo; - else if (x[0] > xhi) xp = xhi; - else xp = x[0]; - if (x[1] < ylo) yp = ylo; - else if (x[1] > yhi) yp = yhi; - else yp = x[1]; - if (x[2] < zlo) zp = zlo; - else if (x[2] > zhi) zp = zhi; - else zp = x[2]; + if (!openflag){ + if (x[0] < xlo) xp = xlo; + else if (x[0] > xhi) xp = xhi; + else xp = x[0]; + if (x[1] < ylo) yp = ylo; + else if (x[1] > yhi) yp = yhi; + else yp = x[1]; + if (x[2] < zlo) zp = zlo; + else if (x[2] > zhi) zp = zhi; + else zp = x[2]; + } + else{ + mindist = BIG; + for (int i = 0; i < 6; i++){ + if (open_faces[i]) continue; + dist = find_closest_point(i,x,xc,yc,zc); + if (dist < mindist){ + xp = xc; + yp = yc; + zp = zc; + mindist = dist; + } + } + } add_contact(0,x,xp,yp,zp); + contact[0].iwall = 0; if (contact[0].r < cutoff) return 1; return 0; } + +/*------------------------------------------------------------------------ + return distance to closest point on surface I of block region + store closest point in xc,yc,zc +--------------------------------------------------------------------------*/ + +double RegBlock::find_closest_point(int i, double *x, + double &xc, double &yc, double &zc) +{ + double dot,d2,d2min; + double xr[3],xproj[3],p[3]; + + xr[0] = x[0] - corners[i][0][0]; + xr[1] = x[1] - corners[i][0][1]; + xr[2] = x[2] - corners[i][0][2]; + dot = face[i][0]*xr[0] + face[i][1]*xr[1] + face[i][2]*xr[2]; + xproj[0] = xr[0] - dot*face[i][0]; + xproj[1] = xr[1] - dot*face[i][1]; + xproj[2] = xr[2] - dot*face[i][2]; + + d2min = BIG; + + // check if point projects inside of face + + if (inside_face(xproj, i)){ + d2 = d2min = dot*dot; + xc = xproj[0] + corners[i][0][0]; + yc = xproj[1] + corners[i][0][1]; + zc = xproj[2] + corners[i][0][2]; + + // check each edge + + } else { + point_on_line_segment(corners[i][0],corners[i][1],x,p); + d2 = (p[0]-x[0])*(p[0]-x[0]) + (p[1]-x[1])*(p[1]-x[1]) + + (p[2]-x[2])*(p[2]-x[2]); + if (d2 < d2min) { + d2min = d2; + xc = p[0]; + yc = p[1]; + zc = p[2]; + } + + point_on_line_segment(corners[i][1],corners[i][2],x,p); + d2 = (p[0]-x[0])*(p[0]-x[0]) + (p[1]-x[1])*(p[1]-x[1]) + + (p[2]-x[2])*(p[2]-x[2]); + if (d2 < d2min) { + d2min = d2; + xc = p[0]; + yc = p[1]; + zc = p[2]; + } + + point_on_line_segment(corners[i][2],corners[i][3],x,p); + d2 = (p[0]-x[0])*(p[0]-x[0]) + (p[1]-x[1])*(p[1]-x[1]) + + (p[2]-x[2])*(p[2]-x[2]); + if (d2 < d2min) { + d2min = d2; + xc = p[0]; + yc = p[1]; + zc = p[2]; + } + + point_on_line_segment(corners[i][3],corners[i][4],x,p); + d2 = (p[0]-x[0])*(p[0]-x[0]) + (p[1]-x[1])*(p[1]-x[1]) + + (p[2]-x[2])*(p[2]-x[2]); + if (d2 < d2min) { + d2min = d2; + xc = p[0]; + yc = p[1]; + zc = p[2]; + } + } + + return d2min; +} + +/*------------------------------------------------------------------------ + determine if projected point is inside given face of the block +--------------------------------------------------------------------------*/ + +int RegBlock::inside_face(double *xproj, int iface) +{ + if (iface < 2) { + if (xproj[1] > 0 && (xproj[1] < yhi-ylo) && + xproj[2] > 0 && (xproj[2] < zhi-zlo)) return 1; + } else if (iface < 4) { + if (xproj[0] > 0 && (xproj[0] < (xhi-xlo)) && + xproj[2] > 0 && (xproj[2] < (zhi-zlo))) return 1; + } else { + if (xproj[0] > 0 && xproj[0] < (xhi-xlo) && + xproj[1] > 0 && xproj[1] < (yhi-ylo)) return 1; + } + + return 0; +} diff --git a/src/region_block.h b/src/region_block.h index fb9dcb3f5..7989ddb8a 100644 --- a/src/region_block.h +++ b/src/region_block.h @@ -1,59 +1,64 @@ /* -*- 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. ------------------------------------------------------------------------- */ #ifdef REGION_CLASS RegionStyle(block,RegBlock) #else #ifndef LMP_REGION_BLOCK_H #define LMP_REGION_BLOCK_H #include "region.h" namespace LAMMPS_NS { class RegBlock : public Region { friend class FixPour; public: RegBlock(class LAMMPS *, int, char **); ~RegBlock(); int inside(double, double, double); int surface_interior(double *, double); int surface_exterior(double *, double); protected: double xlo,xhi,ylo,yhi,zlo,zhi; + double corners[6][4][3]; + double face[6][3]; + + double find_closest_point(int, double *, double &, double &, double &); + int inside_face(double *, int); }; } #endif #endif /* ERROR/WARNING messages: E: Cannot use region INF or EDGE when box does not exist Regions that extend to the box boundaries can only be used after the create_box command has been used. E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. */ diff --git a/src/region_cone.cpp b/src/region_cone.cpp index bc3197a02..786b92d3b 100644 --- a/src/region_cone.cpp +++ b/src/region_cone.cpp @@ -1,584 +1,613 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Pim Schravendijk ------------------------------------------------------------------------- */ #include #include #include #include "region_cone.h" #include "domain.h" #include "error.h" #include "force.h" using namespace LAMMPS_NS; #define BIG 1.0e20 /* ---------------------------------------------------------------------- */ RegCone::RegCone(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) { options(narg-9,&arg[9]); + // check open face settings + + if (openflag && (open_faces[3] || open_faces[4] || open_faces[5])) + error->all(FLERR,"Invalid region cone open setting"); + if (strcmp(arg[2],"x") && strcmp(arg[2],"y") && strcmp(arg[2],"z")) error->all(FLERR,"Illegal region cylinder command"); axis = arg[2][0]; if (axis == 'x') { c1 = yscale*force->numeric(FLERR,arg[3]); c2 = zscale*force->numeric(FLERR,arg[4]); radiuslo = yscale*force->numeric(FLERR,arg[5]); radiushi = yscale*force->numeric(FLERR,arg[6]); } else if (axis == 'y') { c1 = xscale*force->numeric(FLERR,arg[3]); c2 = zscale*force->numeric(FLERR,arg[4]); radiuslo = xscale*force->numeric(FLERR,arg[5]); radiushi = xscale*force->numeric(FLERR,arg[6]); } else if (axis == 'z') { c1 = xscale*force->numeric(FLERR,arg[3]); c2 = yscale*force->numeric(FLERR,arg[4]); radiuslo = xscale*force->numeric(FLERR,arg[5]); radiushi = xscale*force->numeric(FLERR,arg[6]); } if (strcmp(arg[7],"INF") == 0 || strcmp(arg[7],"EDGE") == 0) { if (domain->box_exist == 0) error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (axis == 'x') { if (strcmp(arg[7],"INF") == 0) lo = -BIG; else if (domain->triclinic == 0) lo = domain->boxlo[0]; else lo = domain->boxlo_bound[0]; } if (axis == 'y') { if (strcmp(arg[7],"INF") == 0) lo = -BIG; else if (domain->triclinic == 0) lo = domain->boxlo[1]; else lo = domain->boxlo_bound[1]; } if (axis == 'z') { if (strcmp(arg[7],"INF") == 0) lo = -BIG; else if (domain->triclinic == 0) lo = domain->boxlo[2]; else lo = domain->boxlo_bound[2]; } } else { if (axis == 'x') lo = xscale*force->numeric(FLERR,arg[7]); if (axis == 'y') lo = yscale*force->numeric(FLERR,arg[7]); if (axis == 'z') lo = zscale*force->numeric(FLERR,arg[7]); } if (strcmp(arg[8],"INF") == 0 || strcmp(arg[7],"EDGE") == 0) { if (domain->box_exist == 0) error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (axis == 'x') { if (strcmp(arg[8],"INF") == 0) hi = BIG; else if (domain->triclinic == 0) hi = domain->boxhi[0]; else hi = domain->boxhi_bound[0]; } if (axis == 'y') { if (strcmp(arg[8],"INF") == 0) hi = BIG; if (domain->triclinic == 0) hi = domain->boxhi[1]; else hi = domain->boxhi_bound[1]; } if (axis == 'z') { if (strcmp(arg[8],"INF") == 0) hi = BIG; else if (domain->triclinic == 0) hi = domain->boxhi[2]; else hi = domain->boxhi_bound[2]; } } else { if (axis == 'x') hi = xscale*force->numeric(FLERR,arg[8]); if (axis == 'y') hi = yscale*force->numeric(FLERR,arg[8]); if (axis == 'z') hi = zscale*force->numeric(FLERR,arg[8]); } // error check if (radiuslo < 0.0) error->all(FLERR,"Illegal radius in region cone command"); if (radiushi < 0.0) error->all(FLERR,"Illegal radius in region cone command"); if (radiuslo == 0.0 && radiushi == 0.0) error->all(FLERR,"Illegal radius in region cone command"); if (hi == lo) error->all(FLERR,"Illegal cone length in region cone command"); // extent of cone if (radiuslo > radiushi) maxradius = radiuslo; else maxradius = radiushi; if (interior) { bboxflag = 1; - if (axis == 'x') { extent_xlo = lo; extent_xhi = hi; extent_ylo = c1 - maxradius; extent_yhi = c1 + maxradius; extent_zlo = c2 - maxradius; extent_zhi = c2 + maxradius; } if (axis == 'y') { extent_xlo = c1 - maxradius; extent_xhi = c1 + maxradius; extent_ylo = lo; extent_yhi = hi; extent_zlo = c2 - maxradius; extent_zhi = c2 + maxradius; } if (axis == 'z') { extent_xlo = c1 - maxradius; extent_xhi = c1 + maxradius; extent_ylo = c2 - maxradius; extent_yhi = c2 + maxradius; extent_zlo = lo; extent_zhi = hi; } } else bboxflag = 0; - // particle could be contact cone surface and 2 ends + // particle could be close to cone surface and 2 ends + // particle can only touch surface and 1 end cmax = 3; contact = new Contact[cmax]; + if (interior) tmax = 2; + else tmax = 1; } /* ---------------------------------------------------------------------- */ RegCone::~RegCone() { delete [] contact; } /* ---------------------------------------------------------------------- inside = 1 if x,y,z is inside or on surface inside = 0 if x,y,z is outside and not on surface ------------------------------------------------------------------------- */ int RegCone::inside(double x, double y, double z) { double del1,del2,dist; double currentradius; - int inside = 0; + int inside; if (axis == 'x') { del1 = y - c1; del2 = z - c2; dist = sqrt(del1*del1 + del2*del2); currentradius = radiuslo + (x-lo)*(radiushi-radiuslo)/(hi-lo); if (dist <= currentradius && x >= lo && x <= hi) inside = 1; else inside = 0; } if (axis == 'y') { del1 = x - c1; del2 = z - c2; dist = sqrt(del1*del1 + del2*del2); currentradius = radiuslo + (y-lo)*(radiushi-radiuslo)/(hi-lo); if (dist <= currentradius && y >= lo && y <= hi) inside = 1; else inside = 0; } if (axis == 'z') { del1 = x - c1; del2 = y - c2; dist = sqrt(del1*del1 + del2*del2); currentradius = radiuslo + (z-lo)*(radiushi-radiuslo)/(hi-lo); if (dist <= currentradius && z >= lo && z <= hi) inside = 1; else inside = 0; } return inside; } /* ---------------------------------------------------------------------- contact if 0 <= x < cutoff from one or more inner surfaces of cone can be one contact for each of 3 cone surfaces no contact if outside (possible if called from union/intersect) delxyz = vector from nearest point on cone to x special case: no contact with curved surf if x is on center axis ------------------------------------------------------------------------- */ int RegCone::surface_interior(double *x, double cutoff) { double del1,del2,r,currentradius,delx,dely,delz,dist,delta; double surflo[3],surfhi[3],xs[3]; int n = 0; if (axis == 'x') { del1 = x[1] - c1; del2 = x[2] - c2; r = sqrt(del1*del1 + del2*del2); currentradius = radiuslo + (x[0]-lo)*(radiushi-radiuslo)/(hi-lo); // x is exterior to cone if (r > currentradius || x[0] < lo || x[0] > hi) return 0; // x is interior to cone or on its surface // surflo = pt on outer circle of bottom end plane, same dir as x vs axis // surfhi = pt on outer circle of top end plane, same dir as x vs axis - if (r > 0.0) { + if (r > 0.0 && !open_faces[2]) { surflo[0] = lo; surflo[1] = c1 + del1*radiuslo/r; surflo[2] = c2 + del2*radiuslo/r; surfhi[0] = hi; surfhi[1] = c1 + del1*radiushi/r; surfhi[2] = c2 + del2*radiushi/r; point_on_line_segment(surflo,surfhi,x,xs); delx = x[0] - xs[0]; dely = x[1] - xs[1]; delz = x[2] - xs[2]; dist = sqrt(delx*delx + dely*dely + delz*delz); if (dist < cutoff) { contact[n].r = dist; contact[n].delx = delx; contact[n].dely = dely; contact[n].delz = delz; + contact[n].radius = -2.0*(radiuslo + (xs[0]-lo)* + (radiushi-radiuslo)/(hi-lo)); + contact[n].iwall = 2; n++; } } delta = x[0] - lo; - if (delta < cutoff) { + if (delta < cutoff && !open_faces[0]) { contact[n].r = delta; contact[n].delx = delta; contact[n].dely = contact[n].delz = 0.0; + contact[n].radius = 0; + contact[n].iwall = 0; n++; } delta = hi - x[0]; - if (delta < cutoff) { + if (delta < cutoff && !open_faces[1]) { contact[n].r = delta; contact[n].delx = -delta; contact[n].dely = contact[n].delz = 0.0; + contact[n].radius = 0; + contact[n].iwall = 1; n++; } } else if (axis == 'y') { del1 = x[0] - c1; del2 = x[2] - c2; r = sqrt(del1*del1 + del2*del2); - currentradius = radiuslo + (x[1]-lo)*(radiushi-radiuslo)/(hi-lo); + currentradius = radiuslo + (x[1]-lo)* + (radiushi-radiuslo)/(hi-lo); // y is exterior to cone if (r > currentradius || x[1] < lo || x[1] > hi) return 0; // y is interior to cone or on its surface // surflo = pt on outer circle of bottom end plane, same dir as y vs axis // surfhi = pt on outer circle of top end plane, same dir as y vs axis - if (r > 0.0) { + if (r > 0.0 && !open_faces[2]) { surflo[0] = c1 + del1*radiuslo/r; surflo[1] = lo; surflo[2] = c2 + del2*radiuslo/r; surfhi[0] = c1 + del1*radiushi/r; surfhi[1] = hi; surfhi[2] = c2 + del2*radiushi/r; point_on_line_segment(surflo,surfhi,x,xs); delx = x[0] - xs[0]; dely = x[1] - xs[1]; delz = x[2] - xs[2]; dist = sqrt(delx*delx + dely*dely + delz*delz); if (dist < cutoff) { contact[n].r = dist; contact[n].delx = delx; contact[n].dely = dely; contact[n].delz = delz; + contact[n].iwall = 2; + contact[n].radius = -2.0*(radiuslo + (xs[1]-lo)* + (radiushi-radiuslo)/(hi-lo)); n++; } } delta = x[1] - lo; - if (delta < cutoff) { + if (delta < cutoff && !open_faces[0]) { contact[n].r = delta; contact[n].delz = delta; contact[n].delx = contact[n].dely = 0.0; + contact[n].iwall = 0; + contact[n].radius = 0; n++; } delta = hi - x[1]; - if (delta < cutoff) { + if (delta < cutoff && !open_faces[1]) { contact[n].r = delta; contact[n].delz = -delta; contact[n].delx = contact[n].dely = 0.0; + contact[n].iwall = 1; + contact[n].radius = 0; n++; } } else { del1 = x[0] - c1; del2 = x[1] - c2; r = sqrt(del1*del1 + del2*del2); currentradius = radiuslo + (x[2]-lo)*(radiushi-radiuslo)/(hi-lo); // z is exterior to cone if (r > currentradius || x[2] < lo || x[2] > hi) return 0; // z is interior to cone or on its surface // surflo = pt on outer circle of bottom end plane, same dir as z vs axis // surfhi = pt on outer circle of top end plane, same dir as z vs axis - if (r > 0.0) { + if (r > 0.0 && !open_faces[2]) { surflo[0] = c1 + del1*radiuslo/r; surflo[1] = c2 + del2*radiuslo/r; surflo[2] = lo; surfhi[0] = c1 + del1*radiushi/r; surfhi[1] = c2 + del2*radiushi/r; surfhi[2] = hi; point_on_line_segment(surflo,surfhi,x,xs); delx = x[0] - xs[0]; dely = x[1] - xs[1]; delz = x[2] - xs[2]; dist = sqrt(delx*delx + dely*dely + delz*delz); if (dist < cutoff) { contact[n].r = dist; contact[n].delx = delx; contact[n].dely = dely; contact[n].delz = delz; + contact[n].iwall = 2; + contact[n].radius = -2.0*(radiuslo + (xs[2]-lo)* + (radiushi-radiuslo)/(hi-lo)); n++; } } delta = x[2] - lo; - if (delta < cutoff) { + if (delta < cutoff && !open_faces[0]) { contact[n].r = delta; contact[n].delz = delta; contact[n].delx = contact[n].dely = 0.0; + contact[n].iwall = 0; + contact[n].radius = 0; n++; } delta = hi - x[2]; - if (delta < cutoff) { + if (delta < cutoff && !open_faces[1]) { contact[n].r = delta; contact[n].delz = -delta; contact[n].delx = contact[n].dely = 0.0; + contact[n].iwall = 1; + contact[n].radius = 0; n++; } } return n; } /* ---------------------------------------------------------------------- one contact if 0 <= x < cutoff from outer surface of cone no contact if inside (possible if called from union/intersect) delxyz = vector from nearest point on cone to x ------------------------------------------------------------------------- */ int RegCone::surface_exterior(double *x, double cutoff) { - double del1,del2,r,currentradius,distsq; + double del1,del2,r,currentradius,distsq,distsqprev,crad; double corner1[3],corner2[3],corner3[3],corner4[3],xp[3],nearest[3]; if (axis == 'x') { del1 = x[1] - c1; del2 = x[2] - c2; r = sqrt(del1*del1 + del2*del2); currentradius = radiuslo + (x[0]-lo)*(radiushi-radiuslo)/(hi-lo); + // radius of curvature, only used for granular walls + + double crad = 0.0; + // x is far enough from cone that there is no contact // x is interior to cone - if (r >= maxradius+cutoff || - x[0] <= lo-cutoff || x[0] >= hi+cutoff) return 0; + if (r >= maxradius+cutoff || x[0] <= lo-cutoff || x[0] >= hi+cutoff) + return 0; if (r < currentradius && x[0] > lo && x[0] < hi) return 0; // x is exterior to cone or on its surface // corner1234 = 4 corner pts of half trapezoid = cone surf in plane of x // project x to 3 line segments in half trapezoid (4th is axis of cone) // nearest = point on surface of cone that x is closest to // could be edge of cone // do not add contact point if r >= cutoff corner1[0] = lo; corner1[1] = c1 + del1*radiuslo/r; corner1[2] = c2 + del2*radiuslo/r; corner2[0] = hi; corner2[1] = c1 + del1*radiushi/r; corner2[2] = c2 + del2*radiushi/r; corner3[0] = lo; corner3[1] = c1; corner3[2] = c2; corner4[0] = hi; corner4[1] = c1; corner4[2] = c2; distsq = BIG; - point_on_line_segment(corner1,corner2,x,xp); - distsq = closest(x,xp,nearest,distsq); - point_on_line_segment(corner1,corner3,x,xp); - distsq = closest(x,xp,nearest,distsq); - point_on_line_segment(corner2,corner4,x,xp); - distsq = closest(x,xp,nearest,distsq); + if (!open_faces[2]) { + point_on_line_segment(corner1,corner2,x,xp); + distsq = closest(x,xp,nearest,distsq); + crad = -2.0*(radiuslo + (nearest[0]-lo)*(radiushi-radiuslo)/(hi-lo)); + } + + if (!open_faces[0]) { + point_on_line_segment(corner1,corner3,x,xp); + distsqprev = distsq; + distsq = closest(x,xp,nearest,distsq); + if (distsq < distsqprev) crad = 0.0; + } + + if (!open_faces[1]) { + point_on_line_segment(corner2,corner4,x,xp); + distsqprev = distsq; + distsq = closest(x,xp,nearest,distsq); + if (distsq < distsqprev) crad = 0.0; + } + + if (distsq == BIG) return 0; add_contact(0,x,nearest[0],nearest[1],nearest[2]); + contact[0].radius = crad; + contact[0].iwall = 0; if (contact[0].r < cutoff) return 1; return 0; } else if (axis == 'y') { del1 = x[0] - c1; del2 = x[2] - c2; r = sqrt(del1*del1 + del2*del2); currentradius = radiuslo + (x[1]-lo)*(radiushi-radiuslo)/(hi-lo); // y is far enough from cone that there is no contact // y is interior to cone if (r >= maxradius+cutoff || x[1] <= lo-cutoff || x[1] >= hi+cutoff) return 0; if (r < currentradius && x[1] > lo && x[1] < hi) return 0; // y is exterior to cone or on its surface // corner1234 = 4 corner pts of half trapezoid = cone surf in plane of y // project x to 3 line segments in half trapezoid (4th is axis of cone) // nearest = point on surface of cone that y is closest to // could be edge of cone // do not add contact point if r >= cutoff corner1[0] = c1 + del1*radiuslo/r; corner1[1] = lo; corner1[2] = c2 + del2*radiuslo/r; corner2[0] = c1 + del1*radiushi/r; corner2[1] = hi; corner2[2] = c2 + del2*radiushi/r; corner3[0] = c1; corner3[1] = lo; corner3[2] = c2; corner4[0] = c1; corner4[1] = hi; corner4[2] = c2; distsq = BIG; - point_on_line_segment(corner1,corner2,x,xp); - distsq = closest(x,xp,nearest,distsq); - point_on_line_segment(corner1,corner3,x,xp); - distsq = closest(x,xp,nearest,distsq); - point_on_line_segment(corner2,corner4,x,xp); - distsq = closest(x,xp,nearest,distsq); + + if (!open_faces[2]){ + point_on_line_segment(corner1,corner2,x,xp); + distsq = closest(x,xp,nearest,distsq); + crad = -2.0*(radiuslo + (nearest[1]-lo)*(radiushi-radiuslo)/(hi-lo)); + } + + if (!open_faces[0]) { + point_on_line_segment(corner1,corner3,x,xp); + distsqprev = distsq; + distsq = closest(x,xp,nearest,distsq); + if (distsq < distsqprev) crad = 0; + } + + if (!open_faces[1]) { + point_on_line_segment(corner2,corner4,x,xp); + distsqprev = distsq; + distsq = closest(x,xp,nearest,distsq); + if (distsq < distsqprev) crad = 0; + } add_contact(0,x,nearest[0],nearest[1],nearest[2]); + contact[0].radius = crad; + contact[0].iwall = 0; if (contact[0].r < cutoff) return 1; return 0; } else { del1 = x[0] - c1; del2 = x[1] - c2; r = sqrt(del1*del1 + del2*del2); currentradius = radiuslo + (x[2]-lo)*(radiushi-radiuslo)/(hi-lo); // z is far enough from cone that there is no contact // z is interior to cone - if (r >= maxradius+cutoff || - x[2] <= lo-cutoff || x[2] >= hi+cutoff) return 0; + if (r >= maxradius+cutoff || x[2] <= lo-cutoff || x[2] >= hi+cutoff) + return 0; if (r < currentradius && x[2] > lo && x[2] < hi) return 0; // z is exterior to cone or on its surface // corner1234 = 4 corner pts of half trapezoid = cone surf in plane of z // project x to 3 line segments in half trapezoid (4th is axis of cone) // nearest = point on surface of cone that z is closest to // could be edge of cone // do not add contact point if r >= cutoff corner1[0] = c1 + del1*radiuslo/r; corner1[1] = c2 + del2*radiuslo/r; corner1[2] = lo; corner2[0] = c1 + del1*radiushi/r; corner2[1] = c2 + del2*radiushi/r; corner2[2] = hi; corner3[0] = c1; corner3[1] = c2; corner3[2] = lo; corner4[0] = c1; corner4[1] = c2; corner4[2] = hi; distsq = BIG; - point_on_line_segment(corner1,corner2,x,xp); - distsq = closest(x,xp,nearest,distsq); - point_on_line_segment(corner1,corner3,x,xp); - distsq = closest(x,xp,nearest,distsq); - point_on_line_segment(corner2,corner4,x,xp); - distsq = closest(x,xp,nearest,distsq); + + if (!open_faces[2]){ + point_on_line_segment(corner1,corner2,x,xp); + distsq = closest(x,xp,nearest,distsq); + crad = -2.0*(radiuslo + (nearest[2]-lo)*(radiushi-radiuslo)/(hi-lo)); + } + + if (!open_faces[0]) { + point_on_line_segment(corner1,corner3,x,xp); + distsqprev = distsq; + distsq = closest(x,xp,nearest,distsq); + if (distsq < distsqprev) crad = 0; + } + + if (!open_faces[1]) { + point_on_line_segment(corner2,corner4,x,xp); + distsqprev = distsq; + distsq = closest(x,xp,nearest,distsq); + if (distsq < distsqprev) crad = 0; + } add_contact(0,x,nearest[0],nearest[1],nearest[2]); + contact[0].radius = crad; + contact[0].iwall = 0; if (contact[0].r < cutoff) return 1; return 0; } } -/* ---------------------------------------------------------------------- - find nearest point to C on line segment A,B and return it as D - project (C-A) onto (B-A) - t = length of that projection, normalized by length of (B-A) - t <= 0, C is closest to A - t >= 1, C is closest to B - else closest point is between A and B -------------------------------------------------------------------------- */ - -void RegCone::point_on_line_segment(double *a, double *b, - double *c, double *d) -{ - double ba[3],ca[3]; - - subtract(a,b,ba); - subtract(a,c,ca); - double t = dotproduct(ca,ba) / dotproduct(ba,ba); - - if (t <= 0.0) { - d[0] = a[0]; - d[1] = a[1]; - d[2] = a[2]; - } else if (t >= 1.0) { - d[0] = b[0]; - d[1] = b[1]; - d[2] = b[2]; - } else { - d[0] = a[0] + t*ba[0]; - d[1] = a[1] + t*ba[1]; - d[2] = a[2] + t*ba[2]; - } -} - /* ---------------------------------------------------------------------- */ double RegCone::closest(double *x, double *near, double *nearest, double dsq) { double delx = x[0] - near[0]; double dely = x[1] - near[1]; double delz = x[2] - near[2]; double rsq = delx*delx + dely*dely + delz*delz; if (rsq >= dsq) return dsq; nearest[0] = near[0]; nearest[1] = near[1]; nearest[2] = near[2]; return rsq; } - -/* ---------------------------------------------------------------------- - v3 = v2 - v1 -------------------------------------------------------------------------- */ - -void RegCone::subtract(double *v1, double *v2, double *v3) -{ - v3[0] = v2[0] - v1[0]; - v3[1] = v2[1] - v1[1]; - v3[2] = v2[2] - v1[2]; -} - -/* ---------------------------------------------------------------------- - return dotproduct = v1 dot v2 -------------------------------------------------------------------------- */ - -double RegCone::dotproduct(double *v1, double *v2) -{ - return (v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]); -} diff --git a/src/region_cone.h b/src/region_cone.h index 0f6ac71de..62b2d05a8 100644 --- a/src/region_cone.h +++ b/src/region_cone.h @@ -1,67 +1,63 @@ /* -*- 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. ------------------------------------------------------------------------- */ #ifdef REGION_CLASS RegionStyle(cone,RegCone) #else #ifndef LMP_REGION_CONE_H #define LMP_REGION_CONE_H #include "region.h" namespace LAMMPS_NS { class RegCone : public Region { public: RegCone(class LAMMPS *, int, char **); ~RegCone(); int inside(double, double, double); int surface_interior(double *, double); int surface_exterior(double *, double); private: char axis; double c1,c2; double radiuslo,radiushi; double lo,hi; double maxradius; - void point_on_line_segment(double *, double *, double *, double *); double closest(double *, double *, double *, double); - - void subtract(double *, double *, double *); - double dotproduct(double *, double *); }; } #endif #endif /* ERROR/WARNING messages: E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. E: Cannot use region INF or EDGE when box does not exist Regions that extend to the box boundaries can only be used after the create_box command has been used. */ diff --git a/src/region_cylinder.cpp b/src/region_cylinder.cpp index b77ff2a88..b2935f22c 100644 --- a/src/region_cylinder.cpp +++ b/src/region_cylinder.cpp @@ -1,457 +1,752 @@ /* ---------------------------------------------------------------------- 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 #include #include #include "region_cylinder.h" #include "update.h" #include "domain.h" #include "input.h" #include "variable.h" #include "error.h" #include "force.h" using namespace LAMMPS_NS; #define BIG 1.0e20 enum{CONSTANT,VARIABLE}; /* ---------------------------------------------------------------------- */ RegCylinder::RegCylinder(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) { options(narg-8,&arg[8]); + // check open face settings + + if (openflag && (open_faces[2] || open_faces[3] || + open_faces[4] || open_faces[5])) + error->all(FLERR,"Invalid region cylinder open setting"); + if (strcmp(arg[2],"x") && strcmp(arg[2],"y") && strcmp(arg[2],"z")) error->all(FLERR,"Illegal region cylinder command"); axis = arg[2][0]; if (axis == 'x') { c1 = yscale*force->numeric(FLERR,arg[3]); c2 = zscale*force->numeric(FLERR,arg[4]); } else if (axis == 'y') { c1 = xscale*force->numeric(FLERR,arg[3]); c2 = zscale*force->numeric(FLERR,arg[4]); } else if (axis == 'z') { c1 = xscale*force->numeric(FLERR,arg[3]); c2 = yscale*force->numeric(FLERR,arg[4]); } rstr = NULL; if (strstr(arg[5],"v_") == arg[5]) { int n = strlen(&arg[5][2]) + 1; rstr = new char[n]; strcpy(rstr,&arg[5][2]); radius = 0.0; rstyle = VARIABLE; varshape = 1; variable_check(); shape_update(); } else { radius = force->numeric(FLERR,arg[5]); - if (axis == 'x') radius *= yscale; + if (axis == 'x') radius *= xscale; else radius *= xscale; rstyle = CONSTANT; } if (strcmp(arg[6],"INF") == 0 || strcmp(arg[6],"EDGE") == 0) { if (domain->box_exist == 0) error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (axis == 'x') { if (strcmp(arg[6],"INF") == 0) lo = -BIG; else if (domain->triclinic == 0) lo = domain->boxlo[0]; else lo = domain->boxlo_bound[0]; } if (axis == 'y') { if (strcmp(arg[6],"INF") == 0) lo = -BIG; else if (domain->triclinic == 0) lo = domain->boxlo[1]; else lo = domain->boxlo_bound[1]; } if (axis == 'z') { if (strcmp(arg[6],"INF") == 0) lo = -BIG; else if (domain->triclinic == 0) lo = domain->boxlo[2]; else lo = domain->boxlo_bound[2]; } } else { if (axis == 'x') lo = xscale*force->numeric(FLERR,arg[6]); if (axis == 'y') lo = yscale*force->numeric(FLERR,arg[6]); if (axis == 'z') lo = zscale*force->numeric(FLERR,arg[6]); } if (strcmp(arg[7],"INF") == 0 || strcmp(arg[7],"EDGE") == 0) { if (domain->box_exist == 0) error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (axis == 'x') { if (strcmp(arg[7],"INF") == 0) hi = BIG; else if (domain->triclinic == 0) hi = domain->boxhi[0]; else hi = domain->boxhi_bound[0]; } if (axis == 'y') { if (strcmp(arg[7],"INF") == 0) hi = BIG; else if (domain->triclinic == 0) hi = domain->boxhi[1]; else hi = domain->boxhi_bound[1]; } if (axis == 'z') { if (strcmp(arg[7],"INF") == 0) hi = BIG; else if (domain->triclinic == 0) hi = domain->boxhi[2]; else hi = domain->boxhi_bound[2]; } } else { if (axis == 'x') hi = xscale*force->numeric(FLERR,arg[7]); if (axis == 'y') hi = yscale*force->numeric(FLERR,arg[7]); if (axis == 'z') hi = zscale*force->numeric(FLERR,arg[7]); } // error check if (radius <= 0.0) error->all(FLERR,"Illegal region cylinder command"); // extent of cylinder // for variable radius, uses initial radius if (interior) { bboxflag = 1; if (axis == 'x') { extent_xlo = lo; extent_xhi = hi; extent_ylo = c1 - radius; extent_yhi = c1 + radius; extent_zlo = c2 - radius; extent_zhi = c2 + radius; } if (axis == 'y') { extent_xlo = c1 - radius; extent_xhi = c1 + radius; extent_ylo = lo; extent_yhi = hi; extent_zlo = c2 - radius; extent_zhi = c2 + radius; } if (axis == 'z') { extent_xlo = c1 - radius; extent_xhi = c1 + radius; extent_ylo = c2 - radius; extent_yhi = c2 + radius; extent_zlo = lo; extent_zhi = hi; } } else bboxflag = 0; - // particle could be contact cylinder surface and 2 ends + // particle could be close to cylinder surface and 2 ends + // particle can only touch surface and 1 end cmax = 3; contact = new Contact[cmax]; + if (interior) tmax = 2; + else tmax = 1; } /* ---------------------------------------------------------------------- */ RegCylinder::~RegCylinder() { delete [] rstr; delete [] contact; } /* ---------------------------------------------------------------------- */ void RegCylinder::init() { Region::init(); if (rstr) variable_check(); } /* ---------------------------------------------------------------------- inside = 1 if x,y,z is inside or on surface inside = 0 if x,y,z is outside and not on surface ------------------------------------------------------------------------- */ int RegCylinder::inside(double x, double y, double z) { double del1,del2,dist; int inside; if (axis == 'x') { del1 = y - c1; del2 = z - c2; dist = sqrt(del1*del1 + del2*del2); if (dist <= radius && x >= lo && x <= hi) inside = 1; else inside = 0; } else if (axis == 'y') { del1 = x - c1; del2 = z - c2; dist = sqrt(del1*del1 + del2*del2); if (dist <= radius && y >= lo && y <= hi) inside = 1; else inside = 0; } else { del1 = x - c1; del2 = y - c2; dist = sqrt(del1*del1 + del2*del2); if (dist <= radius && z >= lo && z <= hi) inside = 1; else inside = 0; } return inside; } /* ---------------------------------------------------------------------- contact if 0 <= x < cutoff from one or more inner surfaces of cylinder can be one contact for each of 3 cylinder surfaces no contact if outside (possible if called from union/intersect) delxyz = vector from nearest point on cylinder to x special case: no contact with curved surf if x is on center axis ------------------------------------------------------------------------- */ int RegCylinder::surface_interior(double *x, double cutoff) { double del1,del2,r,delta; int n = 0; if (axis == 'x') { del1 = x[1] - c1; del2 = x[2] - c2; r = sqrt(del1*del1 + del2*del2); // x is exterior to cylinder if (r > radius || x[0] < lo || x[0] > hi) return 0; // x is interior to cylinder or on its surface delta = radius - r; - if (delta < cutoff && r > 0.0) { + if (delta < cutoff && r > 0.0 && !open_faces[2]) { contact[n].r = delta; contact[n].delx = 0.0; contact[n].dely = del1*(1.0-radius/r); contact[n].delz = del2*(1.0-radius/r); + contact[n].radius = -2.0*radius; + contact[n].iwall = 2; + contact[n].varflag = 1; n++; } delta = x[0] - lo; - if (delta < cutoff) { + if (delta < cutoff && !open_faces[0]) { contact[n].r = delta; contact[n].delx = delta; contact[n].dely = contact[n].delz = 0.0; + contact[n].radius = 0; + contact[n].iwall = 0; + contact[n].varflag = 0; n++; } delta = hi - x[0]; - if (delta < cutoff) { + if (delta < cutoff && !open_faces[1]) { contact[n].r = delta; contact[n].delx = -delta; contact[n].dely = contact[n].delz = 0.0; + contact[n].radius = 0; + contact[n].iwall = 1; + contact[n].varflag = 0; n++; } } else if (axis == 'y') { del1 = x[0] - c1; del2 = x[2] - c2; r = sqrt(del1*del1 + del2*del2); // y is exterior to cylinder if (r > radius || x[1] < lo || x[1] > hi) return 0; // y is interior to cylinder or on its surface delta = radius - r; - if (delta < cutoff && r > 0.0) { + if (delta < cutoff && r > 0.0 && !open_faces[2]) { contact[n].r = delta; contact[n].delx = del1*(1.0-radius/r); contact[n].dely = 0.0; contact[n].delz = del2*(1.0-radius/r); + contact[n].radius = -2.0*radius; + contact[n].iwall = 2; + contact[n].varflag = 1; n++; } delta = x[1] - lo; - if (delta < cutoff) { + if (delta < cutoff && !open_faces[0]) { contact[n].r = delta; contact[n].dely = delta; contact[n].delx = contact[n].delz = 0.0; + contact[n].radius = 0; + contact[n].iwall = 0; + contact[n].varflag = 0; n++; } delta = hi - x[1]; - if (delta < cutoff) { + if (delta < cutoff && !open_faces[1]) { contact[n].r = delta; contact[n].dely = -delta; contact[n].delx = contact[n].delz = 0.0; + contact[n].radius = 0; + contact[n].iwall = 1; + contact[n].varflag = 0; n++; } } else { del1 = x[0] - c1; del2 = x[1] - c2; r = sqrt(del1*del1 + del2*del2); // z is exterior to cylinder if (r > radius || x[2] < lo || x[2] > hi) return 0; // z is interior to cylinder or on its surface delta = radius - r; - if (delta < cutoff && r > 0.0) { + if (delta < cutoff && r > 0.0 && !open_faces[2]) { contact[n].r = delta; contact[n].delx = del1*(1.0-radius/r); contact[n].dely = del2*(1.0-radius/r); contact[n].delz = 0.0; + contact[n].radius = -2.0*radius; + contact[n].iwall = 2; + contact[n].varflag = 1; n++; } delta = x[2] - lo; - if (delta < cutoff) { + if (delta < cutoff && !open_faces[0]) { contact[n].r = delta; contact[n].delz = delta; contact[n].delx = contact[n].dely = 0.0; + contact[n].radius = 0; + contact[n].iwall = 0; + contact[n].varflag = 0; n++; } delta = hi - x[2]; - if (delta < cutoff) { + if (delta < cutoff && !open_faces[1]) { contact[n].r = delta; contact[n].delz = -delta; contact[n].delx = contact[n].dely = 0.0; + contact[n].radius = 0; + contact[n].iwall = 1; + contact[n].varflag = 0; n++; } } return n; } /* ---------------------------------------------------------------------- one contact if 0 <= x < cutoff from outer surface of cylinder no contact if inside (possible if called from union/intersect) delxyz = vector from nearest point on cylinder to x ------------------------------------------------------------------------- */ int RegCylinder::surface_exterior(double *x, double cutoff) { double del1,del2,r; double xp,yp,zp; + double dx, dr, dr2, d2, d2prev; + + // radius of curvature for granular + // 0 for flat surfaces (infinite case), 2*radius for curved portion + + double crad = 0.0; + int varflag = 0; if (axis == 'x') { del1 = x[1] - c1; del2 = x[2] - c2; r = sqrt(del1*del1 + del2*del2); // x is far enough from cylinder that there is no contact // x is interior to cylinder if (r >= radius+cutoff || x[0] <= lo-cutoff || x[0] >= hi+cutoff) return 0; if (r < radius && x[0] > lo && x[0] < hi) return 0; // x is exterior to cylinder or on its surface // xp,yp,zp = point on surface of cylinder that x is closest to // could be edge of cylinder // do not add contact point if r >= cutoff - if (r > radius) { - yp = c1 + del1*radius/r; - zp = c2 + del2*radius/r; - } else { - yp = x[1]; - zp = x[2]; + d2prev = BIG; + if (!openflag) { + if (r > radius) { + yp = c1 + del1*radius/r; + zp = c2 + del2*radius/r; + crad = 2.0*radius; + varflag = 1; + } else { + yp = x[1]; + zp = x[2]; + } + if (x[0] < lo) xp = lo; + else if (x[0] > hi) xp = hi; + else xp = x[0]; + } + + // closest point on curved surface + + else { + dr = r - radius; + dr2 = dr*dr; + if (!open_faces[2]){ + yp = c1 + del1*radius/r; + zp = c2 + del2*radius/r; + if (x[0] < lo) { + dx = lo-x[0]; + xp = lo; + } + else if (x[0] > hi) { + dx = x[0]-hi; + xp = hi; + } + else { + dx = 0; + xp = x[0]; + } + d2 = d2prev = dr2 + dx*dx; + } + + // closest point on bottom cap + + if (!open_faces[0]) { + dx = lo - x[0]; + if (r < radius) d2 = dx*dx; + else d2 = dr2 + dx*dx; + if (d2 < d2prev) { + xp = lo; + if (r < radius){ + yp = x[1]; + zp = x[2]; + } + d2prev = d2; + } + } + + // closest point on top cap + + if (!open_faces[1]) { + dx = hi - x[0]; + if (r < radius) d2 = dx*dx; + else d2 = dr2 + dx*dx; + if (d2 < d2prev) { + xp = hi; + if (r < radius){ + yp = x[1]; + zp = x[2]; + } + } + } } - if (x[0] < lo) xp = lo; - else if (x[0] > hi) xp = hi; - else xp = x[0]; add_contact(0,x,xp,yp,zp); + contact[0].radius = crad; + contact[0].varflag = varflag; + contact[0].iwall = 0; if (contact[0].r < cutoff) return 1; return 0; } else if (axis == 'y') { del1 = x[0] - c1; del2 = x[2] - c2; r = sqrt(del1*del1 + del2*del2); // y is far enough from cylinder that there is no contact // y is interior to cylinder if (r >= radius+cutoff || x[1] <= lo-cutoff || x[1] >= hi+cutoff) return 0; if (r < radius && x[1] > lo && x[1] < hi) return 0; // y is exterior to cylinder or on its surface // xp,yp,zp = point on surface of cylinder that x is closest to // could be edge of cylinder // do not add contact point if r >= cutoff - if (r > radius) { - xp = c1 + del1*radius/r; - zp = c2 + del2*radius/r; - } else { - xp = x[0]; - zp = x[2]; + d2prev = BIG; + if (!openflag) { + if (r > radius) { + xp = c1 + del1*radius/r; + zp = c2 + del2*radius/r; + crad = 2.0*radius; + varflag = 1; + } else { + xp = x[0]; + zp = x[2]; + } + if (x[1] < lo) yp = lo; + else if (x[1] > hi) yp = hi; + else yp = x[1]; + } + + // closest point on curved surface + + else { + dr = r - radius; + dr2 = dr*dr; + if (!open_faces[2]){ + xp = c1 + del1*radius/r; + zp = c2 + del2*radius/r; + if (x[1] < lo) { + dx = lo-x[1]; + yp = lo; + } + else if (x[1] > hi) { + dx = x[1]-hi; + yp = hi; + } + else { + dx = 0; + yp = x[1]; + } + d2 = d2prev = dr2 + dx*dx; + } + + // closest point on bottom cap + + if (!open_faces[0]) { + dx = lo - x[1]; + if (r < radius) d2 = dx*dx; + else d2 = dr2 + dx*dx; + if (d2 < d2prev) { + yp = lo; + if (r < radius) { + xp = x[0]; + zp = x[2]; + } + d2prev = d2; + } + } + + // closest point on top cap + + if (!open_faces[1]) { + dx = hi - x[1]; + if (r < radius) d2 = dx*dx; + else d2 = dr2 + dx*dx; + if (d2 < d2prev) { + yp = hi; + if (r < radius) { + xp = x[0]; + zp = x[2]; + } + } + } } - if (x[1] < lo) yp = lo; - else if (x[1] > hi) yp = hi; - else yp = x[1]; add_contact(0,x,xp,yp,zp); + contact[0].radius = crad; + contact[0].varflag = varflag; + contact[0].iwall = 0; if (contact[0].r < cutoff) return 1; return 0; } else { del1 = x[0] - c1; del2 = x[1] - c2; r = sqrt(del1*del1 + del2*del2); // z is far enough from cylinder that there is no contact // z is interior to cylinder if (r >= radius+cutoff || x[2] <= lo-cutoff || x[2] >= hi+cutoff) return 0; if (r < radius && x[2] > lo && x[2] < hi) return 0; // z is exterior to cylinder or on its surface // xp,yp,zp = point on surface of cylinder that x is closest to // could be edge of cylinder // do not add contact point if r >= cutoff - if (r > radius) { - xp = c1 + del1*radius/r; - yp = c2 + del2*radius/r; - } else { - xp = x[0]; - yp = x[1]; + d2prev = BIG; + if (!openflag) { + if (r > radius) { + xp = c1 + del1*radius/r; + yp = c2 + del2*radius/r; + crad = 2.0*radius; + varflag = 1; + } else { + xp = x[0]; + yp = x[1]; + } + if (x[2] < lo) zp = lo; + else if (x[2] > hi) zp = hi; + else zp = x[2]; + } + + // closest point on curved surface + + else { + dr = r - radius; + dr2 = dr*dr; + if (!open_faces[2]){ + xp = c1 + del1*radius/r; + yp = c2 + del2*radius/r; + if (x[2] < lo) { + dx = lo-x[2]; + zp = lo; + } + else if (x[2] > hi) { + dx = x[2]-hi; + zp = hi; + } + else { + dx = 0; + zp = x[2]; + } + d2 = d2prev = dr2 + dx*dx; + } + + // closest point on bottom cap + + if (!open_faces[0]) { + dx = lo - x[2]; + if (r < radius) d2 = dx*dx; + else d2 = dr2 + dx*dx; + if (d2 < d2prev) { + zp = lo; + if (r < radius) { + xp = x[0]; + yp = x[1]; + } + d2prev = d2; + } + } + + // closest point on top cap + + if (!open_faces[1]) { + dx = hi - x[2]; + if (r < radius) d2 = dx*dx; + else d2 = dr2 + dx*dx; + if (d2 < d2prev) { + zp = hi; + if (r < radius) { + xp = x[0]; + yp = x[1]; + } + } + } } - if (x[2] < lo) zp = lo; - else if (x[2] > hi) zp = hi; - else zp = x[2]; add_contact(0,x,xp,yp,zp); + contact[0].radius = crad; + contact[0].varflag = varflag; + contact[0].iwall = 0; if (contact[0].r < cutoff) return 1; return 0; } } /* ---------------------------------------------------------------------- change region shape via variable evaluation ------------------------------------------------------------------------- */ void RegCylinder::shape_update() { radius = input->variable->compute_equal(rvar); if (radius < 0.0) error->one(FLERR,"Variable evaluation in region gave bad value"); - if (axis == 'x') radius *= yscale; - else radius *= xscale; + if (axis == 'x') radius *= xscale; + else if (axis == 'y') radius*= yscale; + else radius *= zscale; } /* ---------------------------------------------------------------------- error check on existence of variable ------------------------------------------------------------------------- */ void RegCylinder::variable_check() { rvar = input->variable->find(rstr); if (rvar < 0) error->all(FLERR,"Variable name for region cylinder does not exist"); if (!input->variable->equalstyle(rvar)) error->all(FLERR,"Variable for region cylinder is invalid style"); } + + +/* ---------------------------------------------------------------------- + Set values needed to calculate velocity due to shape changes. + These values do not depend on the contact, so this function is + called once per timestep by fix/wall/gran/region. + +------------------------------------------------------------------------- */ + +void RegCylinder::set_velocity_shape() +{ + if (axis == 'x'){ + xcenter[0] = 0; + xcenter[1] = c1; + xcenter[2] = c2; + } + else if (axis == 'y'){ + xcenter[0] = c1; + xcenter[1] = 0; + xcenter[2] = c2; + } + else{ + xcenter[0] = c1; + xcenter[1] = c2; + xcenter[2] = 0; + } + forward_transform(xcenter[0], xcenter[1], xcenter[2]); + if (update->ntimestep > 0) rprev = prev[4]; + else rprev = radius; + prev[4] = radius; +} + + + +/* ---------------------------------------------------------------------- + add velocity due to shape change to wall velocity +------------------------------------------------------------------------- */ + +void RegCylinder::velocity_contact_shape(double *vwall, double *xc) +{ + double delx, dely, delz; // Displacement of contact point in x,y,z + if (axis == 'x'){ + delx = 0; + dely = (xc[1] - xcenter[1])*(1 - rprev/radius); + delz = (xc[2] - xcenter[2])*(1 - rprev/radius); + } + else if (axis == 'y'){ + delx = (xc[0] - xcenter[0])*(1 - rprev/radius); + dely = 0; + delz = (xc[2] - xcenter[2])*(1 - rprev/radius); + } + else{ + delx = (xc[0] - xcenter[0])*(1 - rprev/radius); + dely = (xc[1] - xcenter[1])*(1 - rprev/radius); + delz = 0; + } + vwall[0] += delx/update->dt; + vwall[1] += dely/update->dt; + vwall[2] += delz/update->dt; + //printf ("R is %g, prev %g, velocity of wall at %g %g %g is %g %g %g\n",radius,rprev,xc[0],xc[1],xc[2],vwall[0],vwall[1],vwall[2]); +} + diff --git a/src/region_cylinder.h b/src/region_cylinder.h index 247d939c4..bc5255b34 100644 --- a/src/region_cylinder.h +++ b/src/region_cylinder.h @@ -1,81 +1,83 @@ /* -*- 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. ------------------------------------------------------------------------- */ #ifdef REGION_CLASS RegionStyle(cylinder,RegCylinder) #else #ifndef LMP_REGION_CYLINDER_H #define LMP_REGION_CYLINDER_H #include "region.h" namespace LAMMPS_NS { class RegCylinder : public Region { friend class FixPour; public: RegCylinder(class LAMMPS *, int, char **); ~RegCylinder(); void init(); int inside(double, double, double); int surface_interior(double *, double); int surface_exterior(double *, double); void shape_update(); + void set_velocity_shape(); + void velocity_contact_shape(double *, double *); private: char axis; double c1,c2; double radius; double lo,hi; int rstyle,rvar; char *rstr; void variable_check(); }; } #endif #endif /* ERROR/WARNING messages: E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. E: Cannot use region INF or EDGE when box does not exist Regions that extend to the box boundaries can only be used after the create_box command has been used. E: Variable evaluation in region gave bad value Variable returned a radius < 0.0. E: Variable name for region cylinder does not exist Self-explanatory. E: Variable for region cylinder is invalid style Only equal-style varaibles are allowed. */ diff --git a/src/region_intersect.cpp b/src/region_intersect.cpp index bfbe57936..39e8d90d5 100644 --- a/src/region_intersect.cpp +++ b/src/region_intersect.cpp @@ -1,255 +1,320 @@ /* ---------------------------------------------------------------------- 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 #include #include "region_intersect.h" #include "domain.h" #include "error.h" #include "force.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ RegIntersect::RegIntersect(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) { if (narg < 5) error->all(FLERR,"Illegal region command"); int n = force->inumeric(FLERR,arg[2]); if (n < 2) error->all(FLERR,"Illegal region command"); options(narg-(n+3),&arg[n+3]); // build list of regions to intersect // store sub-region IDs in idsub idsub = new char*[n]; list = new int[n]; nregion = 0; int m,iregion; for (int iarg = 0; iarg < n; iarg++) { m = strlen(arg[iarg+3]) + 1; idsub[nregion] = new char[m]; strcpy(idsub[nregion],arg[iarg+3]); iregion = domain->find_region(idsub[nregion]); - if (iregion == -1) + if (iregion == -1) error->all(FLERR,"Region intersect region ID does not exist"); list[nregion++] = iregion; } // this region is variable shape or dynamic if any of sub-regions are Region **regions = domain->regions; for (int ilist = 0; ilist < nregion; ilist++) { if (regions[list[ilist]]->varshape) varshape = 1; if (regions[list[ilist]]->dynamic) dynamic = 1; } // extent of intersection of regions // has bounding box if interior and any sub-region has bounding box bboxflag = 0; for (int ilist = 0; ilist < nregion; ilist++) if (regions[list[ilist]]->bboxflag == 1) bboxflag = 1; if (!interior) bboxflag = 0; if (bboxflag) { int first = 1; for (int ilist = 0; ilist < nregion; ilist++) { if (regions[list[ilist]]->bboxflag == 0) continue; if (first) { extent_xlo = regions[list[ilist]]->extent_xlo; extent_ylo = regions[list[ilist]]->extent_ylo; extent_zlo = regions[list[ilist]]->extent_zlo; extent_xhi = regions[list[ilist]]->extent_xhi; extent_yhi = regions[list[ilist]]->extent_yhi; extent_zhi = regions[list[ilist]]->extent_zhi; first = 0; } extent_xlo = MAX(extent_xlo,regions[list[ilist]]->extent_xlo); extent_ylo = MAX(extent_ylo,regions[list[ilist]]->extent_ylo); extent_zlo = MAX(extent_zlo,regions[list[ilist]]->extent_zlo); extent_xhi = MIN(extent_xhi,regions[list[ilist]]->extent_xhi); extent_yhi = MIN(extent_yhi,regions[list[ilist]]->extent_yhi); extent_zhi = MIN(extent_zhi,regions[list[ilist]]->extent_zhi); } } // possible contacts = sum of possible contacts in all sub-regions + // for near contacts and touching contacts cmax = 0; - for (int ilist = 0; ilist < nregion; ilist++) + size_restart = 0; + for (int ilist = 0; ilist < nregion; ilist++){ cmax += regions[list[ilist]]->cmax; + size_restart += regions[list[ilist]]->size_restart; + } contact = new Contact[cmax]; + + tmax = 0; + for (int ilist = 0; ilist < nregion; ilist++) { + if (interior) tmax += regions[list[ilist]]->tmax; + else tmax++; + } } /* ---------------------------------------------------------------------- */ RegIntersect::~RegIntersect() { for (int ilist = 0; ilist < nregion; ilist++) delete [] idsub[ilist]; delete [] idsub; delete [] list; delete [] contact; } /* ---------------------------------------------------------------------- */ void RegIntersect::init() { Region::init(); // re-build list of sub-regions in case other regions were deleted // error if a sub-region was deleted int iregion; for (int ilist = 0; ilist < nregion; ilist++) { iregion = domain->find_region(idsub[ilist]); - if (iregion == -1) + if (iregion == -1) error->all(FLERR,"Region union region ID does not exist"); list[ilist] = iregion; } // init the sub-regions Region **regions = domain->regions; for (int ilist = 0; ilist < nregion; ilist++) regions[list[ilist]]->init(); } /* ---------------------------------------------------------------------- inside = 1 if x,y,z is match() with all sub-regions else inside = 0 ------------------------------------------------------------------------- */ int RegIntersect::inside(double x, double y, double z) { int ilist; Region **regions = domain->regions; for (ilist = 0; ilist < nregion; ilist++) if (!regions[list[ilist]]->match(x,y,z)) break; if (ilist == nregion) return 1; return 0; } /* ---------------------------------------------------------------------- compute contacts with interior of intersection of sub-regions (1) compute contacts in each sub-region (2) only keep a contact if surface point is match() to all other regions ------------------------------------------------------------------------- */ int RegIntersect::surface_interior(double *x, double cutoff) { int m,ilist,jlist,iregion,jregion,ncontacts; double xs,ys,zs; Region **regions = domain->regions; int n = 0; + int walloffset = 0; for (ilist = 0; ilist < nregion; ilist++) { iregion = list[ilist]; ncontacts = regions[iregion]->surface(x[0],x[1],x[2],cutoff); for (m = 0; m < ncontacts; m++) { xs = x[0] - regions[iregion]->contact[m].delx; ys = x[1] - regions[iregion]->contact[m].dely; zs = x[2] - regions[iregion]->contact[m].delz; for (jlist = 0; jlist < nregion; jlist++) { if (jlist == ilist) continue; jregion = list[jlist]; if (!regions[jregion]->match(xs,ys,zs)) break; } if (jlist == nregion) { contact[n].r = regions[iregion]->contact[m].r; + contact[n].radius = regions[iregion]->contact[m].radius; contact[n].delx = regions[iregion]->contact[m].delx; contact[n].dely = regions[iregion]->contact[m].dely; contact[n].delz = regions[iregion]->contact[m].delz; + contact[n].iwall = regions[iregion]->contact[m].iwall + walloffset; + contact[n].varflag = regions[iregion]->contact[m].varflag; n++; } } + // increment by cmax instead of tmax to insure + // possible wall IDs for sub-regions are non overlapping + walloffset += regions[iregion]->cmax; } return n; } /* ---------------------------------------------------------------------- compute contacts with interior of intersection of sub-regions (1) flip interior/exterior flag of each sub-region (2) compute contacts in each sub-region (3) only keep a contact if surface point is not match() to all other regions (4) flip interior/exterior flags back to original settings this is effectively same algorithm as surface_interior() for RegUnion ------------------------------------------------------------------------- */ int RegIntersect::surface_exterior(double *x, double cutoff) { int m,ilist,jlist,iregion,jregion,ncontacts; double xs,ys,zs; Region **regions = domain->regions; int n = 0; for (ilist = 0; ilist < nregion; ilist++) regions[list[ilist]]->interior ^= 1; for (ilist = 0; ilist < nregion; ilist++) { iregion = list[ilist]; ncontacts = regions[iregion]->surface(x[0],x[1],x[2],cutoff); for (m = 0; m < ncontacts; m++) { xs = x[0] - regions[iregion]->contact[m].delx; ys = x[1] - regions[iregion]->contact[m].dely; zs = x[2] - regions[iregion]->contact[m].delz; for (jlist = 0; jlist < nregion; jlist++) { if (jlist == ilist) continue; jregion = list[jlist]; if (regions[jregion]->match(xs,ys,zs)) break; } if (jlist == nregion) { contact[n].r = regions[iregion]->contact[m].r; + contact[n].radius = regions[iregion]->contact[m].radius; contact[n].delx = regions[iregion]->contact[m].delx; contact[n].dely = regions[iregion]->contact[m].dely; contact[n].delz = regions[iregion]->contact[m].delz; + contact[n].iwall = ilist; + contact[n].varflag = regions[iregion]->contact[m].varflag; n++; } } } for (ilist = 0; ilist < nregion; ilist++) regions[list[ilist]]->interior ^= 1; return n; } /* ---------------------------------------------------------------------- change region shape of all sub-regions ------------------------------------------------------------------------- */ void RegIntersect::shape_update() { Region **regions = domain->regions; for (int ilist = 0; ilist < nregion; ilist++) regions[list[ilist]]->shape_update(); } /* ---------------------------------------------------------------------- move/rotate all sub-regions ------------------------------------------------------------------------- */ void RegIntersect::pretransform() { Region **regions = domain->regions; for (int ilist = 0; ilist < nregion; ilist++) regions[list[ilist]]->pretransform(); } + +/* ---------------------------------------------------------------------- + get translational/angular velocities of all subregions +------------------------------------------------------------------------- */ + +void RegIntersect::set_velocity() +{ + Region **regions = domain->regions; + for (int ilist = 0; ilist < nregion; ilist++) + regions[list[ilist]]->set_velocity(); +} + +/* ---------------------------------------------------------------------- + region writes its current position/angle + needed by fix/wall/gran/region to compute velocity by differencing scheme +------------------------------------------------------------------------- */ + +void RegIntersect::write_restart(FILE *fp) +{ + for (int ilist = 0; ilist < nregion; ilist++) + domain->regions[list[ilist]]->write_restart(fp); +} + +/* ---------------------------------------------------------------------- + region reads its previous position/angle + needed by fix/wall/gran/region to compute velocity by differencing scheme +------------------------------------------------------------------------- */ + +int RegIntersect::restart(char *buf, int n) +{ + for (int ilist = 0; ilist < nregion; ilist++) + n = domain->regions[list[ilist]]->restart(buf, n); + return n; +} + +/* ---------------------------------------------------------------------- + set prev vector to zero +------------------------------------------------------------------------- */ + +void RegIntersect::reset_vel() +{ + for (int ilist = 0; ilist < nregion; ilist++) + domain->regions[list[ilist]]->reset_vel(); +} + diff --git a/src/region_intersect.h b/src/region_intersect.h index 71399fb25..546baac26 100644 --- a/src/region_intersect.h +++ b/src/region_intersect.h @@ -1,66 +1,68 @@ /* -*- 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. ------------------------------------------------------------------------- */ #ifdef REGION_CLASS RegionStyle(intersect,RegIntersect) #else #ifndef LMP_REGION_INTERSECT_H #define LMP_REGION_INTERSECT_H #include "region.h" namespace LAMMPS_NS { class RegIntersect : public Region { public: RegIntersect(class LAMMPS *, int, char **); ~RegIntersect(); void init(); int inside(double, double, double); int surface_interior(double *, double); int surface_exterior(double *, double); void shape_update(); void pretransform(); + void set_velocity(); + void write_restart(FILE *); + int restart(char *, int); + void reset_vel(); private: - int nregion; - int *list; char **idsub; }; } #endif #endif /* ERROR/WARNING messages: E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. E: Region intersect region ID does not exist Self-explanatory. E: Region union region ID does not exist One or more of the region IDs specified by the region union command does not exist. */ diff --git a/src/region_plane.cpp b/src/region_plane.cpp index 38d5b92bc..3c945eb55 100644 --- a/src/region_plane.cpp +++ b/src/region_plane.cpp @@ -1,111 +1,115 @@ /* ---------------------------------------------------------------------- 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 #include #include #include "region_plane.h" #include "error.h" #include "force.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ RegPlane::RegPlane(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) { options(narg-8,&arg[8]); xp = xscale*force->numeric(FLERR,arg[2]); yp = yscale*force->numeric(FLERR,arg[3]); zp = zscale*force->numeric(FLERR,arg[4]); normal[0] = xscale*force->numeric(FLERR,arg[5]); normal[1] = yscale*force->numeric(FLERR,arg[6]); normal[2] = zscale*force->numeric(FLERR,arg[7]); // enforce unit normal double rsq = normal[0]*normal[0] + normal[1]*normal[1] + normal[2]*normal[2]; if (rsq == 0.0) error->all(FLERR,"Illegal region plane command"); normal[0] /= sqrt(rsq); normal[1] /= sqrt(rsq); normal[2] /= sqrt(rsq); // plane has no bounding box bboxflag = 0; - cmax = 1; contact = new Contact[cmax]; + tmax = 1; } /* ---------------------------------------------------------------------- */ RegPlane::~RegPlane() { delete [] contact; } /* ---------------------------------------------------------------------- inside = 1 if x,y,z is on normal side of plane or on plane inside = 0 if x,y,z is on non-normal side of plane and not on plane x,y,z is inside if (x-xp) dot normal >= 0 ------------------------------------------------------------------------- */ int RegPlane::inside(double x, double y, double z) { double dot = (x-xp)*normal[0] + (y-yp)*normal[1] + (z-zp)*normal[2]; if (dot >= 0.0) return 1; return 0; } /* ---------------------------------------------------------------------- one contact if 0 <= x < cutoff from normal side of plane no contact if on other side (possible if called from union/intersect) delxyz = vector from nearest projected point on plane to x ------------------------------------------------------------------------- */ int RegPlane::surface_interior(double *x, double cutoff) { double dot = (x[0]-xp)*normal[0] + (x[1]-yp)*normal[1] + (x[2]-zp)*normal[2]; if (dot < cutoff && dot >= 0.0) { contact[0].r = dot; contact[0].delx = dot*normal[0]; contact[0].dely = dot*normal[1]; contact[0].delz = dot*normal[2]; + contact[0].radius = 0; + contact[0].iwall = 0; return 1; } return 0; } /* ---------------------------------------------------------------------- one contact if 0 <= x < cutoff from non-normal side of plane no contact if on other side (possible if called from union/intersect) delxyz = vector from nearest projected point on plane to x ------------------------------------------------------------------------- */ int RegPlane::surface_exterior(double *x, double cutoff) { double dot = (x[0]-xp)*normal[0] + (x[1]-yp)*normal[1] + (x[2]-zp)*normal[2]; dot = -dot; if (dot < cutoff && dot >= 0.0) { contact[0].r = dot; contact[0].delx = -dot*normal[0]; contact[0].dely = -dot*normal[1]; contact[0].delz = -dot*normal[2]; + contact[0].radius = 0; + contact[0].iwall = 0; return 1; } return 0; } diff --git a/src/region_prism.cpp b/src/region_prism.cpp index 1efd3d964..b8b7b3036 100644 --- a/src/region_prism.cpp +++ b/src/region_prism.cpp @@ -1,510 +1,461 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Pieter in 't Veld (SNL) ------------------------------------------------------------------------- */ #include #include #include #include "region_prism.h" #include "domain.h" #include "force.h" +#include "math_extra.h" #include "error.h" using namespace LAMMPS_NS; #define BIG 1.0e20 /* ---------------------------------------------------------------------- */ RegPrism::RegPrism(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) { options(narg-11,&arg[11]); if (strcmp(arg[2],"INF") == 0 || strcmp(arg[2],"EDGE") == 0) { if (domain->box_exist == 0) error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[2],"INF") == 0) xlo = -BIG; else xlo = domain->boxlo[0]; } else xlo = xscale*force->numeric(FLERR,arg[2]); if (strcmp(arg[3],"INF") == 0 || strcmp(arg[3],"EDGE") == 0) { if (domain->box_exist == 0) error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[3],"INF") == 0) xhi = BIG; else xhi = domain->boxhi[0]; } else xhi = xscale*force->numeric(FLERR,arg[3]); if (strcmp(arg[4],"INF") == 0 || strcmp(arg[4],"EDGE") == 0) { if (domain->box_exist == 0) error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[4],"INF") == 0) ylo = -BIG; else ylo = domain->boxlo[1]; } else ylo = yscale*force->numeric(FLERR,arg[4]); if (strcmp(arg[5],"INF") == 0 || strcmp(arg[5],"EDGE") == 0) { if (domain->box_exist == 0) error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[5],"INF") == 0) yhi = BIG; else yhi = domain->boxhi[1]; } else yhi = yscale*force->numeric(FLERR,arg[5]); if (strcmp(arg[6],"INF") == 0 || strcmp(arg[6],"EDGE") == 0) { if (domain->box_exist == 0) error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[6],"INF") == 0) zlo = -BIG; else zlo = domain->boxlo[2]; } else zlo = zscale*force->numeric(FLERR,arg[6]); if (strcmp(arg[7],"INF") == 0 || strcmp(arg[7],"EDGE") == 0) { if (domain->box_exist == 0) error->all(FLERR,"Cannot use region INF or EDGE when box does not exist"); if (strcmp(arg[7],"INF") == 0) zhi = BIG; else zhi = domain->boxhi[2]; } else zhi = zscale*force->numeric(FLERR,arg[7]); xy = xscale*force->numeric(FLERR,arg[8]); xz = xscale*force->numeric(FLERR,arg[9]); yz = yscale*force->numeric(FLERR,arg[10]); // error check // prism cannot be 0 thickness in any dim, else inverse blows up // non-zero tilt values cannot be used if either dim is INF on both ends if (xlo >= xhi || ylo >= yhi || zlo >= zhi) error->all(FLERR,"Illegal region prism command"); if (xy != 0.0 && xlo == -BIG && xhi == BIG) error->all(FLERR,"Illegal region prism command"); if (xy != 0.0 && ylo == -BIG && yhi == BIG) error->all(FLERR,"Illegal region prism command"); if (xz != 0.0 && xlo == -BIG && xhi == BIG) error->all(FLERR,"Illegal region prism command"); if (xz != 0.0 && zlo == -BIG && zhi == BIG) error->all(FLERR,"Illegal region prism command"); if (yz != 0.0 && ylo == -BIG && yhi == BIG) error->all(FLERR,"Illegal region prism command"); if (yz != 0.0 && zlo == -BIG && zhi == BIG) error->all(FLERR,"Illegal region prism command"); // extent of prism if (interior) { bboxflag = 1; extent_xlo = MIN(xlo,xlo+xy); extent_xlo = MIN(extent_xlo,extent_xlo+xz); extent_ylo = MIN(ylo,ylo+yz); extent_zlo = zlo; extent_xhi = MAX(xhi,xhi+xy); extent_xhi = MAX(extent_xhi,extent_xhi+xz); extent_yhi = MAX(yhi,yhi+yz); extent_zhi = zhi; } else bboxflag = 0; - // particle could contact all 6 planes + // particle could be close to all 6 planes + // particle can only touch 3 planes cmax = 6; contact = new Contact[cmax]; + if (interior) tmax = 3; + else tmax = 1; // h = transformation matrix from tilt coords (0-1) to box coords (xyz) // columns of h are edge vectors of tilted box // hinv = transformation matrix from box coords to tilt coords // both h and hinv are upper triangular // since 1st edge of prism is along x-axis // and bottom face of prism is in xy plane h[0][0] = xhi - xlo; h[0][1] = xy; h[0][2] = xz; h[1][1] = yhi - ylo; h[1][2] = yz; h[2][2] = zhi - zlo; hinv[0][0] = 1.0/h[0][0]; hinv[0][1] = -h[0][1] / (h[0][0]*h[1][1]); hinv[0][2] = (h[0][1]*h[1][2] - h[0][2]*h[1][1]) / (h[0][0]*h[1][1]*h[2][2]); hinv[1][1] = 1.0/h[1][1]; hinv[1][2] = -h[1][2] / (h[1][1]*h[2][2]); hinv[2][2] = 1.0/h[2][2]; // corners = 8 corner points of prism // order = x varies fastest, then y, finally z // clo/chi = lo and hi corner pts of prism a[0] = xhi-xlo; a[1] = 0.0; a[2] = 0.0; b[0] = xy; b[1] = yhi-ylo; b[2] = 0.0; c[0] = xz; c[1] = yz; c[2] = zhi-zlo; clo[0] = corners[0][0] = xlo; clo[1] = corners[0][1] = ylo; clo[2] = corners[0][2] = zlo; corners[1][0] = xlo + a[0]; corners[1][1] = ylo + a[1]; corners[1][2] = zlo + a[2]; corners[2][0] = xlo + b[0]; corners[2][1] = ylo + b[1]; corners[2][2] = zlo + b[2]; corners[3][0] = xlo + a[0] + b[0]; corners[3][1] = ylo + a[1] + b[1]; corners[3][2] = zlo + a[2] + b[2]; corners[4][0] = xlo + c[0]; corners[4][1] = ylo + c[1]; corners[4][2] = zlo + c[2]; corners[5][0] = xlo + a[0] + c[0]; corners[5][1] = ylo + a[1] + c[1]; corners[5][2] = zlo + a[2] + c[2]; corners[6][0] = xlo + b[0] + c[0]; corners[6][1] = ylo + b[1] + c[1]; corners[6][2] = zlo + b[2] + c[2]; chi[0] = corners[7][0] = xlo + a[0] + b[0] + c[0]; chi[1] = corners[7][1] = ylo + a[1] + b[1] + c[1]; chi[2] = corners[7][2] = zlo + a[2] + b[2] + c[2]; // face = 6 inward-facing unit normals to prism faces // order = xy plane, xz plane, yz plane - cross(a,b,face[0]); - cross(b,a,face[1]); - cross(c,a,face[2]); - cross(a,c,face[3]); - cross(b,c,face[4]); - cross(c,b,face[5]); + MathExtra::cross3(a,b,face[0]); + MathExtra::cross3(b,a,face[1]); + MathExtra::cross3(c,a,face[2]); + MathExtra::cross3(a,c,face[3]); + MathExtra::cross3(b,c,face[4]); + MathExtra::cross3(c,b,face[5]); + + // remap open face indices to be consistent + + if (openflag) { + int temp[6]; + for (int i = 0; i < 6; i++) + temp[i] = open_faces[i]; + open_faces[0] = temp[4]; + open_faces[1] = temp[5]; + open_faces[2] = temp[2]; + open_faces[3] = temp[3]; + open_faces[4] = temp[0]; + open_faces[5] = temp[1]; + } - for (int i = 0; i < 6; i++) normalize(face[i]); + for (int i = 0; i < 6; i++) MathExtra::norm3(face[i]); // tri = 3 vertices (0-7) in each of 12 triangles on 6 faces // verts in each tri are ordered so that right-hand rule gives inward norm // order = xy plane, xz plane, yz plane tri[0][0] = 0; tri[0][1] = 1; tri[0][2] = 3; tri[1][0] = 0; tri[1][1] = 3; tri[1][2] = 2; tri[2][0] = 4; tri[2][1] = 7; tri[2][2] = 5; tri[3][0] = 4; tri[3][1] = 6; tri[3][2] = 7; tri[4][0] = 0; tri[4][1] = 4; tri[4][2] = 5; tri[5][0] = 0; tri[5][1] = 5; tri[5][2] = 1; tri[6][0] = 2; tri[6][1] = 7; tri[6][2] = 6; tri[7][0] = 2; tri[7][1] = 3; tri[7][2] = 7; tri[8][0] = 2; tri[8][1] = 6; tri[8][2] = 4; tri[9][0] = 2; tri[9][1] = 4; tri[9][2] = 0; tri[10][0] = 1; tri[10][1] = 5; tri[10][2] = 7; tri[11][0] = 1; tri[11][1] = 7; tri[11][2] = 3; } /* ---------------------------------------------------------------------- */ RegPrism::~RegPrism() { delete [] contact; } /* ---------------------------------------------------------------------- inside = 1 if x,y,z is inside or on surface inside = 0 if x,y,z is outside and not on surface abc = Hinv * (xyz - xyz/lo) abc = tilt coords (0-1) Hinv = transformation matrix from box coords to tilt coords xyz = box coords xyz/lo = lower-left corner of prism ------------------------------------------------------------------------- */ int RegPrism::inside(double x, double y, double z) { double a = hinv[0][0]*(x-xlo) + hinv[0][1]*(y-ylo) + hinv[0][2]*(z-zlo); double b = hinv[1][1]*(y-ylo) + hinv[1][2]*(z-zlo); double c = hinv[2][2]*(z-zlo); if (a >= 0.0 && a <= 1.0 && b >= 0.0 && b <= 1.0 && c >= 0.0 && c <= 1.0) return 1; return 0; } /* ---------------------------------------------------------------------- contact if 0 <= x < cutoff from one or more inner surfaces of prism can be one contact for each of 6 faces no contact if outside (possible if called from union/intersect) delxyz = vector from nearest point on prism to x ------------------------------------------------------------------------- */ int RegPrism::surface_interior(double *x, double cutoff) { int i; double dot; double *corner; // x is exterior to prism for (i = 0; i < 6; i++) { if (i % 2) corner = chi; else corner = clo; dot = (x[0]-corner[0])*face[i][0] + (x[1]-corner[1])*face[i][1] + (x[2]-corner[2])*face[i][2]; if (dot < 0.0) return 0; } // x is interior to prism or on its surface int n = 0; - for (int i = 0; i < 6; i++) { + for (i = 0; i < 6; i++) { + if (open_faces[i]) continue; if (i % 2) corner = chi; else corner = clo; dot = (x[0]-corner[0])*face[i][0] + (x[1]-corner[1])*face[i][1] + (x[2]-corner[2])*face[i][2]; if (dot < cutoff) { contact[n].r = dot; contact[n].delx = dot*face[i][0]; contact[n].dely = dot*face[i][1]; contact[n].delz = dot*face[i][2]; + contact[n].radius = 0; + contact[n].iwall = i; n++; } } return n; } /* ---------------------------------------------------------------------- one contact if 0 <= x < cutoff from outer surface of prism no contact if inside (possible if called from union/intersect) delxyz = vector from nearest point on prism to x ------------------------------------------------------------------------- */ int RegPrism::surface_exterior(double *x, double cutoff) { int i; double dot; double *corner; double xp,yp,zp; // x is far enough from prism that there is no contact for (i = 0; i < 6; i++) { if (i % 2) corner = chi; else corner = clo; dot = (x[0]-corner[0])*face[i][0] + (x[1]-corner[1])*face[i][1] + (x[2]-corner[2])*face[i][2]; if (dot <= -cutoff) return 0; } // x is interior to prism for (i = 0; i < 6; i++) { if (i % 2) corner = chi; else corner = clo; dot = (x[0]-corner[0])*face[i][0] + (x[1]-corner[1])*face[i][1] + (x[2]-corner[2])*face[i][2]; if (dot <= 0.0) break; } if (i == 6) return 0; // x is exterior to prism or on its surface // xp,yp,zp = point on surface of prism that x is closest to // could be edge or corner pt of prism // do not add contact point if r >= cutoff find_nearest(x,xp,yp,zp); add_contact(0,x,xp,yp,zp); + contact[0].radius = 0; + contact[0].iwall = 0; if (contact[0].r < cutoff) return 1; return 0; } /* ---------------------------------------------------------------------- x is exterior to prism or on its surface return (xp,yp,zp) = nearest pt to x that is on surface of prism ------------------------------------------------------------------------- */ void RegPrism::find_nearest(double *x, double &xp, double &yp, double &zp) { int i,j,k,iface; double xproj[3],xline[3],nearest[3]; double dot; // generate successive xnear points, one nearest to x is (xp,yp,zp) // loop over 6 faces and 2 triangles in each face // xproj = x projected to plane of triangle // if xproj is inside or on triangle boundary, that is xnear // else: loop over 3 edges of triangle // compute distance to edge line // xnear = nearest point on line to xproj, bounded by segment end pts double distsq = BIG; for (int itri = 0; itri < 12; itri++) { iface = itri/2; + if (open_faces[iface]) continue; i = tri[itri][0]; j = tri[itri][1]; k = tri[itri][2]; dot = (x[0]-corners[i][0])*face[iface][0] + (x[1]-corners[i][1])*face[iface][1] + (x[2]-corners[i][2])*face[iface][2]; xproj[0] = x[0] - dot*face[iface][0]; xproj[1] = x[1] - dot*face[iface][1]; xproj[2] = x[2] - dot*face[iface][2]; - if (inside_tri(xproj,corners[i],corners[j],corners[k],face[iface])) + if (inside_tri(xproj,corners[i],corners[j],corners[k],face[iface])){ distsq = closest(x,xproj,nearest,distsq); + } else { point_on_line_segment(corners[i],corners[j],xproj,xline); distsq = closest(x,xline,nearest,distsq); point_on_line_segment(corners[j],corners[k],xproj,xline); distsq = closest(x,xline,nearest,distsq); point_on_line_segment(corners[i],corners[k],xproj,xline); distsq = closest(x,xline,nearest,distsq); } } xp = nearest[0]; yp = nearest[1]; zp = nearest[2]; } /* ---------------------------------------------------------------------- test if x is inside triangle with vertices v1,v2,v3 norm = normal to triangle, defined by right-hand rule for v1,v2,v3 ordering edge = edge vector of triangle pvec = vector from vertex to x xproduct = cross product of edge with pvec if xproduct dot norm < 0.0 for any of 3 edges, then x is outside triangle ------------------------------------------------------------------------- */ int RegPrism::inside_tri(double *x, double *v1, double *v2, double *v3, double *norm) { double edge[3],pvec[3],xproduct[3]; - subtract(v1,v2,edge); - subtract(v1,x,pvec); - cross(edge,pvec,xproduct); - if (dotproduct(xproduct,norm) < 0.0) return 0; + MathExtra::sub3(v2,v1,edge); + MathExtra::sub3(x,v1,pvec); + MathExtra::cross3(edge,pvec,xproduct); + if (MathExtra::dot3(xproduct,norm) < 0.0) return 0; - subtract(v2,v3,edge); - subtract(v2,x,pvec); - cross(edge,pvec,xproduct); - if (dotproduct(xproduct,norm) < 0.0) return 0; + MathExtra::sub3(v3,v2,edge); + MathExtra::sub3(x,v2,pvec); + MathExtra::cross3(edge,pvec,xproduct); + if (MathExtra::dot3(xproduct,norm) < 0.0) return 0; - subtract(v3,v1,edge); - subtract(v3,x,pvec); - cross(edge,pvec,xproduct); - if (dotproduct(xproduct,norm) < 0.0) return 0; + MathExtra::sub3(v1,v3,edge); + MathExtra::sub3(x,v3,pvec); + MathExtra::cross3(edge,pvec,xproduct); + if (MathExtra::dot3(xproduct,norm) < 0.0) return 0; return 1; } -/* ---------------------------------------------------------------------- - find nearest point to C on line segment A,B and return it as D - project (C-A) onto (B-A) - t = length of that projection, normalized by length of (B-A) - t <= 0, C is closest to A - t >= 1, C is closest to B - else closest point is between A and B -------------------------------------------------------------------------- */ - -void RegPrism::point_on_line_segment(double *a, double *b, - double *c, double *d) -{ - double ba[3],ca[3]; - - subtract(a,b,ba); - subtract(a,c,ca); - double t = dotproduct(ca,ba) / dotproduct(ba,ba); - - if (t <= 0.0) { - d[0] = a[0]; - d[1] = a[1]; - d[2] = a[2]; - } else if (t >= 1.0) { - d[0] = b[0]; - d[1] = b[1]; - d[2] = b[2]; - } else { - d[0] = a[0] + t*ba[0]; - d[1] = a[1] + t*ba[1]; - d[2] = a[2] + t*ba[2]; - } -} - /* ---------------------------------------------------------------------- */ double RegPrism::closest(double *x, double *near, double *nearest, double dsq) { double delx = x[0] - near[0]; double dely = x[1] - near[1]; double delz = x[2] - near[2]; double rsq = delx*delx + dely*dely + delz*delz; if (rsq >= dsq) return dsq; nearest[0] = near[0]; nearest[1] = near[1]; nearest[2] = near[2]; return rsq; } - -/* ---------------------------------------------------------------------- - v3 = v2 - v1 -------------------------------------------------------------------------- */ - -void RegPrism::subtract(double *v1, double *v2, double *v3) -{ - v3[0] = v2[0] - v1[0]; - v3[1] = v2[1] - v1[1]; - v3[2] = v2[2] - v1[2]; -} - -/* ---------------------------------------------------------------------- - v3 = v1 x v2 -------------------------------------------------------------------------- */ - -void RegPrism::cross(double *v1, double *v2, double *v3) -{ - v3[0] = v1[1]*v2[2] - v1[2]*v2[1]; - v3[1] = v1[2]*v2[0] - v1[0]*v2[2]; - v3[2] = v1[0]*v2[1] - v1[1]*v2[0]; -} - -/* ---------------------------------------------------------------------- - return dotproduct = v1 dot v2 -------------------------------------------------------------------------- */ - -double RegPrism::dotproduct(double *v1, double *v2) -{ - return (v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]); -} - -/* ---------------------------------------------------------------------- */ - -void RegPrism::normalize(double *x) -{ - double invlen = 1.0/sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]); - x[0] *= invlen; - x[1] *= invlen; - x[2] *= invlen; -} diff --git a/src/region_prism.h b/src/region_prism.h index fefe20ce8..4b518def7 100644 --- a/src/region_prism.h +++ b/src/region_prism.h @@ -1,77 +1,71 @@ /* -*- 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. ------------------------------------------------------------------------- */ #ifdef REGION_CLASS RegionStyle(prism,RegPrism) #else #ifndef LMP_REGION_PRISM_H #define LMP_REGION_PRISM_H #include "region.h" namespace LAMMPS_NS { class RegPrism : public Region { friend class CreateBox; public: RegPrism(class LAMMPS *, int, char **); ~RegPrism(); int inside(double, double, double); int surface_interior(double *, double); int surface_exterior(double *, double); private: double xlo,xhi,ylo,yhi,zlo,zhi; double xy,xz,yz; double h[3][3],hinv[3][3]; int dimension; double a[3],b[3],c[3]; // edge vectors of region double clo[3],chi[3]; // opposite corners of prism double face[6][3]; // unit normals of 6 prism faces double corners[8][3]; // 8 corner pts of prism int tri[12][3]; // 3 corner pts of 12 triangles (2 per face) void find_nearest(double *, double &, double &, double &); int inside_tri(double *, double *, double *, double *, double *); - void point_on_line_segment(double *, double *, double *, double *); double closest(double *, double *, double *, double); - - void subtract(double *, double *, double *); - void cross(double *, double *, double *); - double dotproduct(double *, double *); - void normalize(double *); }; } #endif #endif /* ERROR/WARNING messages: E: Cannot use region INF or EDGE when box does not exist Regions that extend to the box boundaries can only be used after the create_box command has been used. E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. */ diff --git a/src/region_sphere.cpp b/src/region_sphere.cpp index 409a497f1..2f51baacc 100644 --- a/src/region_sphere.cpp +++ b/src/region_sphere.cpp @@ -1,180 +1,226 @@ /* ---------------------------------------------------------------------- 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 #include #include #include "region_sphere.h" #include "update.h" #include "input.h" #include "variable.h" #include "error.h" #include "force.h" using namespace LAMMPS_NS; enum{CONSTANT,VARIABLE}; /* ---------------------------------------------------------------------- */ RegSphere::RegSphere(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) { options(narg-6,&arg[6]); xc = xscale*force->numeric(FLERR,arg[2]); yc = yscale*force->numeric(FLERR,arg[3]); zc = zscale*force->numeric(FLERR,arg[4]); rstr = NULL; if (strstr(arg[5],"v_") == arg[5]) { int n = strlen(&arg[5][2]) + 1; rstr = new char[n]; strcpy(rstr,&arg[5][2]); radius = 0.0; rstyle = VARIABLE; varshape = 1; variable_check(); shape_update(); } else { radius = xscale*force->numeric(FLERR,arg[5]); rstyle = CONSTANT; } // error check if (radius < 0.0) error->all(FLERR,"Illegal region sphere command"); // extent of sphere // for variable radius, uses initial radius if (interior) { bboxflag = 1; extent_xlo = xc - radius; extent_xhi = xc + radius; extent_ylo = yc - radius; extent_yhi = yc + radius; extent_zlo = zc - radius; extent_zhi = zc + radius; } else bboxflag = 0; cmax = 1; contact = new Contact[cmax]; + tmax = 1; } /* ---------------------------------------------------------------------- */ RegSphere::~RegSphere() { delete [] rstr; delete [] contact; } /* ---------------------------------------------------------------------- */ void RegSphere::init() { Region::init(); if (rstr) variable_check(); } /* ---------------------------------------------------------------------- inside = 1 if x,y,z is inside or on surface inside = 0 if x,y,z is outside and not on surface ------------------------------------------------------------------------- */ int RegSphere::inside(double x, double y, double z) { double delx = x - xc; double dely = y - yc; double delz = z - zc; double r = sqrt(delx*delx + dely*dely + delz*delz); if (r <= radius) return 1; return 0; } /* ---------------------------------------------------------------------- one contact if 0 <= x < cutoff from inner surface of sphere no contact if outside (possible if called from union/intersect) delxyz = vector from nearest point on sphere to x special case: no contact if x is at center of sphere ------------------------------------------------------------------------- */ int RegSphere::surface_interior(double *x, double cutoff) { double delx = x[0] - xc; double dely = x[1] - yc; double delz = x[2] - zc; double r = sqrt(delx*delx + dely*dely + delz*delz); if (r > radius || r == 0.0) return 0; double delta = radius - r; if (delta < cutoff) { contact[0].r = delta; contact[0].delx = delx*(1.0-radius/r); contact[0].dely = dely*(1.0-radius/r); contact[0].delz = delz*(1.0-radius/r); + contact[0].radius = -radius; + contact[0].iwall = 0; + contact[0].varflag = 1; return 1; } return 0; } /* ---------------------------------------------------------------------- one contact if 0 <= x < cutoff from outer surface of sphere no contact if inside (possible if called from union/intersect) delxyz = vector from nearest point on sphere to x ------------------------------------------------------------------------- */ int RegSphere::surface_exterior(double *x, double cutoff) { double delx = x[0] - xc; double dely = x[1] - yc; double delz = x[2] - zc; double r = sqrt(delx*delx + dely*dely + delz*delz); if (r < radius) return 0; double delta = r - radius; if (delta < cutoff) { contact[0].r = delta; contact[0].delx = delx*(1.0-radius/r); contact[0].dely = dely*(1.0-radius/r); contact[0].delz = delz*(1.0-radius/r); + contact[0].radius = radius; + contact[0].iwall = 0; + contact[0].varflag = 1; return 1; } return 0; } /* ---------------------------------------------------------------------- change region shape via variable evaluation ------------------------------------------------------------------------- */ void RegSphere::shape_update() { radius = xscale * input->variable->compute_equal(rvar); if (radius < 0.0) error->one(FLERR,"Variable evaluation in region gave bad value"); } /* ---------------------------------------------------------------------- error check on existence of variable ------------------------------------------------------------------------- */ void RegSphere::variable_check() { rvar = input->variable->find(rstr); if (rvar < 0) error->all(FLERR,"Variable name for region sphere does not exist"); if (!input->variable->equalstyle(rvar)) error->all(FLERR,"Variable for region sphere is invalid style"); } + + +/* ---------------------------------------------------------------------- + Set values needed to calculate velocity due to shape changes. + These values do not depend on the contact, so this function is + called once per timestep by fix/wall/gran/region. + +------------------------------------------------------------------------- */ + +void RegSphere::set_velocity_shape() +{ + xcenter[0] = xc; + xcenter[1] = yc; + xcenter[2] = zc; + forward_transform(xcenter[0], xcenter[1], xcenter[2]); + if (update->ntimestep > 0) rprev = prev[4]; + else rprev = radius; + prev[4] = radius; +} + + + +/* ---------------------------------------------------------------------- + add velocity due to shape change to wall velocity +------------------------------------------------------------------------- */ + +void RegSphere::velocity_contact_shape(double *vwall, double *xc) +{ + double delx, dely, delz; // Displacement of contact point in x,y,z + + delx = (xc[0] - xcenter[0])*(1 - rprev/radius); + dely = (xc[1] - xcenter[1])*(1 - rprev/radius); + delz = (xc[2] - xcenter[2])*(1 - rprev/radius); + + vwall[0] += delx/update->dt; + vwall[1] += dely/update->dt; + vwall[2] += delz/update->dt; +} + diff --git a/src/region_sphere.h b/src/region_sphere.h index 283493fb3..9e1fb4e73 100644 --- a/src/region_sphere.h +++ b/src/region_sphere.h @@ -1,71 +1,74 @@ /* -*- 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. ------------------------------------------------------------------------- */ #ifdef REGION_CLASS RegionStyle(sphere,RegSphere) #else #ifndef LMP_REGION_SPHERE_H #define LMP_REGION_SPHERE_H #include "region.h" namespace LAMMPS_NS { class RegSphere : public Region { public: RegSphere(class LAMMPS *, int, char **); ~RegSphere(); void init(); int inside(double, double, double); int surface_interior(double *, double); int surface_exterior(double *, double); void shape_update(); + void set_velocity_shape(); + void velocity_contact_shape(double *, double *); + private: double xc,yc,zc; double radius; int rstyle,rvar; char *rstr; void variable_check(); }; } #endif #endif /* ERROR/WARNING messages: E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. E: Variable evaluation in region gave bad value Variable returned a radius < 0.0. E: Variable name for region sphere does not exist Self-explanatory. E: Variable for region sphere is invalid style Only equal-style varaibles are allowed. */ diff --git a/src/region_union.cpp b/src/region_union.cpp index 2772d7b4d..b516af98d 100644 --- a/src/region_union.cpp +++ b/src/region_union.cpp @@ -1,247 +1,313 @@ /* ---------------------------------------------------------------------- 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 #include #include "region_union.h" #include "domain.h" #include "error.h" #include "force.h" using namespace LAMMPS_NS; #define BIG 1.0e20 /* ---------------------------------------------------------------------- */ RegUnion::RegUnion(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg) { if (narg < 5) error->all(FLERR,"Illegal region command"); int n = force->inumeric(FLERR,arg[2]); if (n < 2) error->all(FLERR,"Illegal region command"); options(narg-(n+3),&arg[n+3]); // build list of region indices to union // store sub-region IDs in idsub idsub = new char*[n]; list = new int[n]; nregion = 0; int m,iregion; for (int iarg = 0; iarg < n; iarg++) { m = strlen(arg[iarg+3]) + 1; idsub[nregion] = new char[m]; strcpy(idsub[nregion],arg[iarg+3]); iregion = domain->find_region(idsub[nregion]); - if (iregion == -1) + if (iregion == -1) error->all(FLERR,"Region union region ID does not exist"); list[nregion++] = iregion; } // this region is variable shape or dynamic if any of sub-regions are Region **regions = domain->regions; for (int ilist = 0; ilist < nregion; ilist++) { if (regions[list[ilist]]->varshape) varshape = 1; if (regions[list[ilist]]->dynamic) dynamic = 1; + if (regions[list[ilist]]->moveflag) moveflag = 1; + if (regions[list[ilist]]->rotateflag) rotateflag = 1; } // extent of union of regions // has bounding box if interior and all sub-regions have bounding box bboxflag = 1; for (int ilist = 0; ilist < nregion; ilist++) if (regions[list[ilist]]->bboxflag == 0) bboxflag = 0; if (!interior) bboxflag = 0; if (bboxflag) { extent_xlo = extent_ylo = extent_zlo = BIG; extent_xhi = extent_yhi = extent_zhi = -BIG; for (int ilist = 0; ilist < nregion; ilist++) { extent_xlo = MIN(extent_xlo,regions[list[ilist]]->extent_xlo); extent_ylo = MIN(extent_ylo,regions[list[ilist]]->extent_ylo); extent_zlo = MIN(extent_zlo,regions[list[ilist]]->extent_zlo); extent_xhi = MAX(extent_xhi,regions[list[ilist]]->extent_xhi); extent_yhi = MAX(extent_yhi,regions[list[ilist]]->extent_yhi); extent_zhi = MAX(extent_zhi,regions[list[ilist]]->extent_zhi); } } // possible contacts = sum of possible contacts in all sub-regions + // for near contacts and touching contacts cmax = 0; - for (int ilist = 0; ilist < nregion; ilist++) + size_restart = 0; + for (int ilist = 0; ilist < nregion; ilist++){ cmax += regions[list[ilist]]->cmax; + size_restart += regions[list[ilist]]->size_restart; + } contact = new Contact[cmax]; + + tmax = 0; + for (int ilist = 0; ilist < nregion; ilist++) { + if (interior) tmax += regions[list[ilist]]->tmax; + else tmax++; + } } /* ---------------------------------------------------------------------- */ RegUnion::~RegUnion() { for (int ilist = 0; ilist < nregion; ilist++) delete [] idsub[ilist]; delete [] idsub; delete [] list; delete [] contact; } /* ---------------------------------------------------------------------- */ void RegUnion::init() { Region::init(); // re-build list of sub-regions in case other regions were deleted // error if a sub-region was deleted int iregion; for (int ilist = 0; ilist < nregion; ilist++) { iregion = domain->find_region(idsub[ilist]); - if (iregion == -1) + if (iregion == -1) error->all(FLERR,"Region union region ID does not exist"); list[ilist] = iregion; } // init the sub-regions Region **regions = domain->regions; for (int ilist = 0; ilist < nregion; ilist++) regions[list[ilist]]->init(); } /* ---------------------------------------------------------------------- inside = 1 if x,y,z is match() with any sub-region else inside = 0 ------------------------------------------------------------------------- */ int RegUnion::inside(double x, double y, double z) { int ilist; Region **regions = domain->regions; for (ilist = 0; ilist < nregion; ilist++) if (regions[list[ilist]]->match(x,y,z)) break; if (ilist == nregion) return 0; return 1; } /* ---------------------------------------------------------------------- compute contacts with interior of union of sub-regions (1) compute contacts in each sub-region (2) only keep a contact if surface point is not match() to all other regions ------------------------------------------------------------------------- */ int RegUnion::surface_interior(double *x, double cutoff) { int m,ilist,jlist,iregion,jregion,ncontacts; double xs,ys,zs; Region **regions = domain->regions; int n = 0; + int walloffset = 0 ; for (ilist = 0; ilist < nregion; ilist++) { iregion = list[ilist]; ncontacts = regions[iregion]->surface(x[0],x[1],x[2],cutoff); for (m = 0; m < ncontacts; m++) { xs = x[0] - regions[iregion]->contact[m].delx; ys = x[1] - regions[iregion]->contact[m].dely; zs = x[2] - regions[iregion]->contact[m].delz; for (jlist = 0; jlist < nregion; jlist++) { if (jlist == ilist) continue; jregion = list[jlist]; - if (regions[jregion]->match(xs,ys,zs)) break; + if (regions[jregion]->match(xs,ys,zs) && + !regions[jregion]->openflag) break; } if (jlist == nregion) { contact[n].r = regions[iregion]->contact[m].r; + contact[n].radius = regions[iregion]->contact[m].radius; contact[n].delx = regions[iregion]->contact[m].delx; contact[n].dely = regions[iregion]->contact[m].dely; contact[n].delz = regions[iregion]->contact[m].delz; + contact[n].iwall = regions[iregion]->contact[m].iwall + walloffset; + contact[n].varflag = regions[iregion]->contact[m].varflag; n++; } } + // increment by cmax instead of tmax to insure + // possible wall IDs for sub-regions are non overlapping + walloffset += regions[iregion]->cmax; } return n; } /* ---------------------------------------------------------------------- compute contacts with exterior of union of sub-regions (1) flip interior/exterior flag of each sub-region (2) compute contacts in each sub-region (3) only keep a contact if surface point is match() to all other regions (4) flip interior/exterior flags back to original settings this is effectively same algorithm as surface_interior() for RegIntersect ------------------------------------------------------------------------- */ int RegUnion::surface_exterior(double *x, double cutoff) { int m,ilist,jlist,iregion,jregion,ncontacts; double xs,ys,zs; Region **regions = domain->regions; int n = 0; for (ilist = 0; ilist < nregion; ilist++) regions[list[ilist]]->interior ^= 1; for (ilist = 0; ilist < nregion; ilist++) { iregion = list[ilist]; ncontacts = regions[iregion]->surface(x[0],x[1],x[2],cutoff); for (m = 0; m < ncontacts; m++) { xs = x[0] - regions[iregion]->contact[m].delx; ys = x[1] - regions[iregion]->contact[m].dely; zs = x[2] - regions[iregion]->contact[m].delz; for (jlist = 0; jlist < nregion; jlist++) { if (jlist == ilist) continue; jregion = list[jlist]; if (!regions[jregion]->match(xs,ys,zs)) break; } if (jlist == nregion) { contact[n].r = regions[iregion]->contact[m].r; + contact[n].radius = regions[iregion]->contact[m].radius; contact[n].delx = regions[iregion]->contact[m].delx; contact[n].dely = regions[iregion]->contact[m].dely; contact[n].delz = regions[iregion]->contact[m].delz; + contact[n].iwall = ilist; + contact[n].r = regions[iregion]->contact[m].varflag; n++; } } } for (ilist = 0; ilist < nregion; ilist++) regions[list[ilist]]->interior ^= 1; return n; } /* ---------------------------------------------------------------------- change region shape of all sub-regions ------------------------------------------------------------------------- */ void RegUnion::shape_update() { Region **regions = domain->regions; for (int ilist = 0; ilist < nregion; ilist++) regions[list[ilist]]->shape_update(); } /* ---------------------------------------------------------------------- move/rotate all sub-regions ------------------------------------------------------------------------- */ void RegUnion::pretransform() { Region **regions = domain->regions; for (int ilist = 0; ilist < nregion; ilist++) regions[list[ilist]]->pretransform(); } + +/* ---------------------------------------------------------------------- + get translational/angular velocities of all subregions +------------------------------------------------------------------------- */ + +void RegUnion::set_velocity() +{ + Region **regions = domain->regions; + for (int ilist = 0; ilist < nregion; ilist++) + regions[list[ilist]]->set_velocity(); +} +/* ---------------------------------------------------------------------- + region writes its current position/angle + needed by fix/wall/gran/region to compute velocity by differencing scheme +------------------------------------------------------------------------- */ + +void RegUnion::write_restart(FILE *fp) +{ + for (int ilist = 0; ilist < nregion; ilist++) + domain->regions[list[ilist]]->write_restart(fp); +} + +/* ---------------------------------------------------------------------- + region reads its previous position/angle + needed by fix/wall/gran/region to compute velocity by differencing scheme +------------------------------------------------------------------------- */ + +int RegUnion::restart(char *buf, int n) +{ + for (int ilist = 0; ilist < nregion; ilist++) + n = domain->regions[list[ilist]]->restart(buf, n); + return n; +} + +/* ---------------------------------------------------------------------- + set prev vector to zero +------------------------------------------------------------------------- */ + +void RegUnion::reset_vel() +{ + for (int ilist = 0; ilist < nregion; ilist++) + domain->regions[list[ilist]]->reset_vel(); +} diff --git a/src/region_union.h b/src/region_union.h index 7cc32b3ed..091688d66 100644 --- a/src/region_union.h +++ b/src/region_union.h @@ -1,62 +1,64 @@ /* -*- 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. ------------------------------------------------------------------------- */ #ifdef REGION_CLASS RegionStyle(union,RegUnion) #else #ifndef LMP_REGION_UNION_H #define LMP_REGION_UNION_H #include "region.h" namespace LAMMPS_NS { class RegUnion : public Region { public: RegUnion(class LAMMPS *, int, char **); ~RegUnion(); void init(); int inside(double, double, double); int surface_interior(double *, double); int surface_exterior(double *, double); void shape_update(); void pretransform(); + void set_velocity(); + void write_restart(FILE *); + int restart(char *, int); + void reset_vel(); private: - int nregion; - int *list; char **idsub; }; } #endif #endif /* ERROR/WARNING messages: E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. E: Region union region ID does not exist One or more of the region IDs specified by the region union command does not exist. */ diff --git a/src/special.cpp b/src/special.cpp index ae566ec4f..c4de11e09 100644 --- a/src/special.cpp +++ b/src/special.cpp @@ -1,1148 +1,1153 @@ /* ---------------------------------------------------------------------- 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 #include #include "special.h" #include "atom.h" #include "atom_vec.h" #include "force.h" #include "comm.h" #include "modify.h" #include "fix.h" #include "accelerator_kokkos.h" #include "memory.h" #include "error.h" +#include "atom_masks.h" using namespace LAMMPS_NS; // allocate space for static class variable Special *Special::sptr; /* ---------------------------------------------------------------------- */ Special::Special(LAMMPS *lmp) : Pointers(lmp) { MPI_Comm_rank(world,&me); MPI_Comm_size(world,&nprocs); onetwo = onethree = onefour = NULL; } /* ---------------------------------------------------------------------- */ Special::~Special() { memory->destroy(onetwo); memory->destroy(onethree); memory->destroy(onefour); } /* ---------------------------------------------------------------------- create 1-2, 1-3, 1-4 lists of topology neighbors store in onetwo, onethree, onefour for each atom store 3 counters in nspecial[i] ------------------------------------------------------------------------- */ void Special::build() { int i,j,k,size; int max,maxall,nbuf; tagint *buf; MPI_Barrier(world); int nlocal = atom->nlocal; tagint *tag = atom->tag; int *num_bond = atom->num_bond; tagint **bond_atom = atom->bond_atom; int **nspecial = atom->nspecial; if (me == 0 && screen) { const double * const special_lj = force->special_lj; const double * const special_coul = force->special_coul; fprintf(screen,"Finding 1-2 1-3 1-4 neighbors ...\n" " Special bond factors lj: %-10g %-10g %-10g\n" " Special bond factors coul: %-10g %-10g %-10g\n", special_lj[1],special_lj[2],special_lj[3], special_coul[1],special_coul[2],special_coul[3]); } // initialize nspecial counters to 0 for (i = 0; i < nlocal; i++) { nspecial[i][0] = 0; nspecial[i][1] = 0; nspecial[i][2] = 0; } // ----------------------------------------------------- // compute nspecial[i][0] = # of 1-2 neighbors of atom i // ----------------------------------------------------- // bond partners stored by atom itself for (i = 0; i < nlocal; i++) nspecial[i][0] = num_bond[i]; // if newton_bond off, then done // else only counted 1/2 of all bonds, so count other half if (force->newton_bond) { // nbufmax = largest buffer needed to hold info from any proc // info for each atom = global tag of 2nd atom in each bond nbuf = 0; for (i = 0; i < nlocal; i++) nbuf += num_bond[i]; memory->create(buf,nbuf,"special:buf"); // fill buffer with global tags of bond partners of my atoms size = 0; for (i = 0; i < nlocal; i++) for (j = 0; j < num_bond[i]; j++) buf[size++] = bond_atom[i][j]; // cycle buffer around ring of procs back to self // when receive buffer, scan tags for atoms I own // when find one, increment nspecial count for that atom sptr = this; comm->ring(size,sizeof(tagint),buf,1,ring_one,NULL); memory->destroy(buf); } // ---------------------------------------------------- // create onetwo[i] = list of 1-2 neighbors for atom i // ---------------------------------------------------- max = 0; for (i = 0; i < nlocal; i++) max = MAX(max,nspecial[i][0]); MPI_Allreduce(&max,&maxall,1,MPI_INT,MPI_MAX,world); if (me == 0) { if (screen) fprintf(screen," %d = max # of 1-2 neighbors\n",maxall); if (logfile) fprintf(logfile," %d = max # of 1-2 neighbors\n",maxall); } memory->create(onetwo,nlocal,maxall,"special:onetwo"); // count = accumulating counter memory->create(count,nlocal,"special:count"); for (i = 0; i < nlocal; i++) count[i] = 0; // add bond partners stored by atom to onetwo list for (i = 0; i < nlocal; i++) for (j = 0; j < num_bond[i]; j++) onetwo[i][count[i]++] = bond_atom[i][j]; // if newton_bond off, then done // else only stored 1/2 of all bonds, so store other half if (force->newton_bond) { // nbufmax = largest buffer needed to hold info from any proc // info for each atom = 2 global tags in each bond nbuf = 0; for (i = 0; i < nlocal; i++) nbuf += 2*num_bond[i]; memory->create(buf,nbuf,"special:buf"); // fill buffer with global tags of both atoms in bond size = 0; for (i = 0; i < nlocal; i++) for (j = 0; j < num_bond[i]; j++) { buf[size++] = tag[i]; buf[size++] = bond_atom[i][j]; } // cycle buffer around ring of procs back to self // when receive buffer, scan 2nd-atom tags for atoms I own // when find one, add 1st-atom tag to onetwo list for 2nd atom sptr = this; comm->ring(size,sizeof(tagint),buf,2,ring_two,NULL); memory->destroy(buf); } memory->destroy(count); // ----------------------------------------------------- // done if special_bond weights for 1-3, 1-4 are set to 1.0 // ----------------------------------------------------- if (force->special_lj[2] == 1.0 && force->special_coul[2] == 1.0 && force->special_lj[3] == 1.0 && force->special_coul[3] == 1.0) { dedup(); combine(); fix_alteration(); return; } // ----------------------------------------------------- // compute nspecial[i][1] = # of 1-3 neighbors of atom i // ----------------------------------------------------- // nbufmax = largest buffer needed to hold info from any proc // info for each atom = 2 scalars + list of 1-2 neighbors nbuf = 0; for (i = 0; i < nlocal; i++) nbuf += 2 + nspecial[i][0]; memory->create(buf,nbuf,"special:buf"); // fill buffer with: // (1) = counter for 1-3 neighbors, initialized to 0 // (2) = # of 1-2 neighbors // (3:N) = list of 1-2 neighbors size = 0; for (i = 0; i < nlocal; i++) { buf[size++] = 0; buf[size++] = nspecial[i][0]; for (j = 0; j < nspecial[i][0]; j++) buf[size++] = onetwo[i][j]; } // cycle buffer around ring of procs back to self // when receive buffer, scan list of 1-2 neighbors for atoms I own // when find one, increment 1-3 count by # of 1-2 neighbors of my atom, // subtracting one since my list will contain original atom sptr = this; comm->ring(size,sizeof(tagint),buf,3,ring_three,buf); // extract count from buffer that has cycled back to me // nspecial[i][1] = # of 1-3 neighbors of atom i j = 0; for (i = 0; i < nlocal; i++) { nspecial[i][1] = buf[j]; j += 2 + nspecial[i][0]; } memory->destroy(buf); // ---------------------------------------------------- // create onethree[i] = list of 1-3 neighbors for atom i // ---------------------------------------------------- max = 0; for (i = 0; i < nlocal; i++) max = MAX(max,nspecial[i][1]); MPI_Allreduce(&max,&maxall,1,MPI_INT,MPI_MAX,world); if (me == 0) { if (screen) fprintf(screen," %d = max # of 1-3 neighbors\n",maxall); if (logfile) fprintf(logfile," %d = max # of 1-3 neighbors\n",maxall); } memory->create(onethree,nlocal,maxall,"special:onethree"); // nbufmax = largest buffer needed to hold info from any proc // info for each atom = 4 scalars + list of 1-2 neighs + list of 1-3 neighs nbuf = 0; for (i = 0; i < nlocal; i++) nbuf += 4 + nspecial[i][0] + nspecial[i][1]; memory->create(buf,nbuf,"special:buf"); // fill buffer with: // (1) = global tag of original atom // (2) = # of 1-2 neighbors // (3) = # of 1-3 neighbors // (4) = counter for 1-3 neighbors, initialized to 0 // (5:N) = list of 1-2 neighbors // (N+1:2N) space for list of 1-3 neighbors size = 0; for (i = 0; i < nlocal; i++) { buf[size++] = tag[i]; buf[size++] = nspecial[i][0]; buf[size++] = nspecial[i][1]; buf[size++] = 0; for (j = 0; j < nspecial[i][0]; j++) buf[size++] = onetwo[i][j]; size += nspecial[i][1]; } // cycle buffer around ring of procs back to self // when receive buffer, scan list of 1-2 neighbors for atoms I own // when find one, add its neighbors to 1-3 list // increment the count in buf(i+4) // exclude the atom whose tag = original // this process may include duplicates but they will be culled later sptr = this; comm->ring(size,sizeof(tagint),buf,4,ring_four,buf); // fill onethree with buffer values that have been returned to me // sanity check: accumulated buf[i+3] count should equal // nspecial[i][1] for each atom j = 0; for (i = 0; i < nlocal; i++) { if (buf[j+3] != nspecial[i][1]) error->one(FLERR,"1-3 bond count is inconsistent"); j += 4 + nspecial[i][0]; for (k = 0; k < nspecial[i][1]; k++) onethree[i][k] = buf[j++]; } memory->destroy(buf); // done if special_bond weights for 1-4 are set to 1.0 if (force->special_lj[3] == 1.0 && force->special_coul[3] == 1.0) { dedup(); if (force->special_angle) angle_trim(); combine(); fix_alteration(); return; } // ----------------------------------------------------- // compute nspecial[i][2] = # of 1-4 neighbors of atom i // ----------------------------------------------------- // nbufmax = largest buffer needed to hold info from any proc // info for each atom = 2 scalars + list of 1-3 neighbors nbuf = 0; for (i = 0; i < nlocal; i++) nbuf += 2 + nspecial[i][1]; memory->create(buf,nbuf,"special:buf"); // fill buffer with: // (1) = counter for 1-4 neighbors, initialized to 0 // (2) = # of 1-3 neighbors // (3:N) = list of 1-3 neighbors size = 0; for (i = 0; i < nlocal; i++) { buf[size++] = 0; buf[size++] = nspecial[i][1]; for (j = 0; j < nspecial[i][1]; j++) buf[size++] = onethree[i][j]; } // cycle buffer around ring of procs back to self // when receive buffer, scan list of 1-3 neighbors for atoms I own // when find one, increment 1-4 count by # of 1-2 neighbors of my atom // may include duplicates and original atom but they will be culled later sptr = this; comm->ring(size,sizeof(tagint),buf,5,ring_five,buf); // extract count from buffer that has cycled back to me // nspecial[i][2] = # of 1-4 neighbors of atom i j = 0; for (i = 0; i < nlocal; i++) { nspecial[i][2] = buf[j]; j += 2 + nspecial[i][1]; } memory->destroy(buf); // ---------------------------------------------------- // create onefour[i] = list of 1-4 neighbors for atom i // ---------------------------------------------------- max = 0; for (i = 0; i < nlocal; i++) max = MAX(max,nspecial[i][2]); MPI_Allreduce(&max,&maxall,1,MPI_INT,MPI_MAX,world); if (me == 0) { if (screen) fprintf(screen," %d = max # of 1-4 neighbors\n",maxall); if (logfile) fprintf(logfile," %d = max # of 1-4 neighbors\n",maxall); } memory->create(onefour,nlocal,maxall,"special:onefour"); // nbufmax = largest buffer needed to hold info from any proc // info for each atom = 3 scalars + list of 1-3 neighs + list of 1-4 neighs nbuf = 0; for (i = 0; i < nlocal; i++) nbuf += 3 + nspecial[i][1] + nspecial[i][2]; memory->create(buf,nbuf,"special:buf"); // fill buffer with: // (1) = # of 1-3 neighbors // (2) = # of 1-4 neighbors // (3) = counter for 1-4 neighbors, initialized to 0 // (4:N) = list of 1-3 neighbors // (N+1:2N) space for list of 1-4 neighbors size = 0; for (i = 0; i < nlocal; i++) { buf[size++] = nspecial[i][1]; buf[size++] = nspecial[i][2]; buf[size++] = 0; for (j = 0; j < nspecial[i][1]; j++) buf[size++] = onethree[i][j]; size += nspecial[i][2]; } // cycle buffer around ring of procs back to self // when receive buffer, scan list of 1-3 neighbors for atoms I own // when find one, add its neighbors to 1-4 list // incrementing the count in buf(i+4) // this process may include duplicates but they will be culled later sptr = this; comm->ring(size,sizeof(tagint),buf,6,ring_six,buf); // fill onefour with buffer values that have been returned to me // sanity check: accumulated buf[i+2] count should equal // nspecial[i][2] for each atom j = 0; for (i = 0; i < nlocal; i++) { if (buf[j+2] != nspecial[i][2]) error->one(FLERR,"1-4 bond count is inconsistent"); j += 3 + nspecial[i][1]; for (k = 0; k < nspecial[i][2]; k++) onefour[i][k] = buf[j++]; } memory->destroy(buf); dedup(); if (force->special_angle) angle_trim(); if (force->special_dihedral) dihedral_trim(); combine(); fix_alteration(); } /* ---------------------------------------------------------------------- remove duplicates within each of onetwo, onethree, onefour individually ------------------------------------------------------------------------- */ void Special::dedup() { int i,j; tagint m; // clear map so it can be used as scratch space atom->map_clear(); // use map to cull duplicates // exclude original atom explicitly // adjust onetwo, onethree, onefour values to reflect removed duplicates // must unset map for each atom int **nspecial = atom->nspecial; tagint *tag = atom->tag; int nlocal = atom->nlocal; int unique; for (i = 0; i < nlocal; i++) { unique = 0; atom->map_one(tag[i],0); for (j = 0; j < nspecial[i][0]; j++) { m = onetwo[i][j]; if (atom->map(m) < 0) { onetwo[i][unique++] = m; atom->map_one(m,0); } } nspecial[i][0] = unique; atom->map_one(tag[i],-1); for (j = 0; j < unique; j++) atom->map_one(onetwo[i][j],-1); } for (i = 0; i < nlocal; i++) { unique = 0; atom->map_one(tag[i],0); for (j = 0; j < nspecial[i][1]; j++) { m = onethree[i][j]; if (atom->map(m) < 0) { onethree[i][unique++] = m; atom->map_one(m,0); } } nspecial[i][1] = unique; atom->map_one(tag[i],-1); for (j = 0; j < unique; j++) atom->map_one(onethree[i][j],-1); } for (i = 0; i < nlocal; i++) { unique = 0; atom->map_one(tag[i],0); for (j = 0; j < nspecial[i][2]; j++) { m = onefour[i][j]; if (atom->map(m) < 0) { onefour[i][unique++] = m; atom->map_one(m,0); } } nspecial[i][2] = unique; atom->map_one(tag[i],-1); for (j = 0; j < unique; j++) atom->map_one(onefour[i][j],-1); } // re-create map atom->nghost = 0; atom->map_set(); } /* ---------------------------------------------------------------------- concatenate onetwo, onethree, onefour into master atom->special list remove duplicates between 3 lists, leave dup in first list it appears in convert nspecial[0], nspecial[1], nspecial[2] into cumulative counters ------------------------------------------------------------------------- */ void Special::combine() { int i,j; tagint m; int me; MPI_Comm_rank(world,&me); int **nspecial = atom->nspecial; tagint *tag = atom->tag; int nlocal = atom->nlocal; // ---------------------------------------------------- // compute culled maxspecial = max # of special neighs of any atom // ---------------------------------------------------- // clear map so it can be used as scratch space atom->map_clear(); // unique = # of unique nspecial neighbors of one atom // cull duplicates using map to check for them // exclude original atom explicitly // must unset map for each atom int unique; int maxspecial = 0; for (i = 0; i < nlocal; i++) { unique = 0; atom->map_one(tag[i],0); for (j = 0; j < nspecial[i][0]; j++) { m = onetwo[i][j]; if (atom->map(m) < 0) { unique++; atom->map_one(m,0); } } for (j = 0; j < nspecial[i][1]; j++) { m = onethree[i][j]; if (atom->map(m) < 0) { unique++; atom->map_one(m,0); } } for (j = 0; j < nspecial[i][2]; j++) { m = onefour[i][j]; if (atom->map(m) < 0) { unique++; atom->map_one(m,0); } } maxspecial = MAX(maxspecial,unique); atom->map_one(tag[i],-1); for (j = 0; j < nspecial[i][0]; j++) atom->map_one(onetwo[i][j],-1); for (j = 0; j < nspecial[i][1]; j++) atom->map_one(onethree[i][j],-1); for (j = 0; j < nspecial[i][2]; j++) atom->map_one(onefour[i][j],-1); } // compute global maxspecial, must be at least 1 // add in extra factor from special_bonds command // allocate correct special array with same nmax, new maxspecial // previously allocated one must be destroyed // must make AtomVec class update its ptr to special MPI_Allreduce(&maxspecial,&atom->maxspecial,1,MPI_INT,MPI_MAX,world); atom->maxspecial += force->special_extra; atom->maxspecial = MAX(atom->maxspecial,1); if (me == 0) { if (screen) fprintf(screen," %d = max # of special neighbors\n",atom->maxspecial); if (logfile) fprintf(logfile," %d = max # of special neighbors\n",atom->maxspecial); } if (lmp->kokkos) { AtomKokkos* atomKK = (AtomKokkos*) atom; + atomKK->modified(Host,SPECIAL_MASK); + atomKK->sync(Device,SPECIAL_MASK); memory->grow_kokkos(atomKK->k_special,atom->special, atom->nmax,atom->maxspecial,"atom:special"); + atomKK->modified(Device,SPECIAL_MASK); + atomKK->sync(Host,SPECIAL_MASK); } else { memory->destroy(atom->special); memory->create(atom->special,atom->nmax,atom->maxspecial,"atom:special"); } atom->avec->grow_reset(); tagint **special = atom->special; // ---------------------------------------------------- // fill special array with 1-2, 1-3, 1-4 neighs for each atom // ---------------------------------------------------- // again use map to cull duplicates // exclude original atom explicitly // adjust nspecial[i] values to reflect removed duplicates // nspecial[i][1] and nspecial[i][2] now become cumulative counters for (i = 0; i < nlocal; i++) { unique = 0; atom->map_one(tag[i],0); for (j = 0; j < nspecial[i][0]; j++) { m = onetwo[i][j]; if (atom->map(m) < 0) { special[i][unique++] = m; atom->map_one(m,0); } } nspecial[i][0] = unique; for (j = 0; j < nspecial[i][1]; j++) { m = onethree[i][j]; if (atom->map(m) < 0) { special[i][unique++] = m; atom->map_one(m,0); } } nspecial[i][1] = unique; for (j = 0; j < nspecial[i][2]; j++) { m = onefour[i][j]; if (atom->map(m) < 0) { special[i][unique++] = m; atom->map_one(m,0); } } nspecial[i][2] = unique; atom->map_one(tag[i],-1); for (j = 0; j < nspecial[i][2]; j++) atom->map_one(special[i][j],-1); } // re-create map atom->nghost = 0; atom->map_set(); } /* ---------------------------------------------------------------------- trim list of 1-3 neighbors by checking defined angles delete a 1-3 neigh if they are not end atoms of a defined angle and if they are not 1,3 or 2,4 atoms of a defined dihedral ------------------------------------------------------------------------- */ void Special::angle_trim() { int i,j,m,n; int *num_angle = atom->num_angle; int *num_dihedral = atom->num_dihedral; tagint **angle_atom1 = atom->angle_atom1; tagint **angle_atom3 = atom->angle_atom3; tagint **dihedral_atom1 = atom->dihedral_atom1; tagint **dihedral_atom2 = atom->dihedral_atom2; tagint **dihedral_atom3 = atom->dihedral_atom3; tagint **dihedral_atom4 = atom->dihedral_atom4; int **nspecial = atom->nspecial; int nlocal = atom->nlocal; // stats on old 1-3 neighbor counts double onethreecount = 0.0; for (i = 0; i < nlocal; i++) onethreecount += nspecial[i][1]; double allcount; MPI_Allreduce(&onethreecount,&allcount,1,MPI_DOUBLE,MPI_SUM,world); if (me == 0) { if (screen) fprintf(screen, " %g = # of 1-3 neighbors before angle trim\n",allcount); if (logfile) fprintf(logfile, " %g = # of 1-3 neighbors before angle trim\n",allcount); } // if angles or dihedrals are defined, // flag each 1-3 neigh if it appears in an angle or dihedral if ((num_angle && atom->nangles) || (num_dihedral && atom->ndihedrals)) { // dflag = flag for 1-3 neighs of all owned atoms int maxcount = 0; for (i = 0; i < nlocal; i++) maxcount = MAX(maxcount,nspecial[i][1]); memory->create(dflag,nlocal,maxcount,"special::dflag"); for (i = 0; i < nlocal; i++) { n = nspecial[i][1]; for (j = 0; j < n; j++) dflag[i][j] = 0; } // nbufmax = largest buffer needed to hold info from any proc // info for each atom = list of 1,3 atoms in each angle stored by atom // and list of 1,3 and 2,4 atoms in each dihedral stored by atom int nbuf = 0; for (i = 0; i < nlocal; i++) { if (num_angle && atom->nangles) nbuf += 2*num_angle[i]; if (num_dihedral && atom->ndihedrals) nbuf += 2*2*num_dihedral[i]; } int *buf; memory->create(buf,nbuf,"special:buf"); // fill buffer with list of 1,3 atoms in each angle // and with list of 1,3 and 2,4 atoms in each dihedral int size = 0; if (num_angle && atom->nangles) for (i = 0; i < nlocal; i++) for (j = 0; j < num_angle[i]; j++) { buf[size++] = angle_atom1[i][j]; buf[size++] = angle_atom3[i][j]; } if (num_dihedral && atom->ndihedrals) for (i = 0; i < nlocal; i++) for (j = 0; j < num_dihedral[i]; j++) { buf[size++] = dihedral_atom1[i][j]; buf[size++] = dihedral_atom3[i][j]; buf[size++] = dihedral_atom2[i][j]; buf[size++] = dihedral_atom4[i][j]; } // cycle buffer around ring of procs back to self // when receive buffer, scan list of 1,3 atoms looking for atoms I own // when find one, scan its 1-3 neigh list and mark I,J as in an angle sptr = this; comm->ring(size,sizeof(tagint),buf,7,ring_seven,NULL); // delete 1-3 neighbors if they are not flagged in dflag for (i = 0; i < nlocal; i++) { m = 0; for (j = 0; j < nspecial[i][1]; j++) if (dflag[i][j]) onethree[i][m++] = onethree[i][j]; nspecial[i][1] = m; } // clean up memory->destroy(dflag); memory->destroy(buf); // if no angles or dihedrals are defined, delete all 1-3 neighs } else { for (i = 0; i < nlocal; i++) nspecial[i][1] = 0; } // stats on new 1-3 neighbor counts onethreecount = 0.0; for (i = 0; i < nlocal; i++) onethreecount += nspecial[i][1]; MPI_Allreduce(&onethreecount,&allcount,1,MPI_DOUBLE,MPI_SUM,world); if (me == 0) { if (screen) fprintf(screen, " %g = # of 1-3 neighbors after angle trim\n",allcount); if (logfile) fprintf(logfile, " %g = # of 1-3 neighbors after angle trim\n",allcount); } } /* ---------------------------------------------------------------------- trim list of 1-4 neighbors by checking defined dihedrals delete a 1-4 neigh if they are not end atoms of a defined dihedral ------------------------------------------------------------------------- */ void Special::dihedral_trim() { int i,j,m,n; int *num_dihedral = atom->num_dihedral; tagint **dihedral_atom1 = atom->dihedral_atom1; tagint **dihedral_atom4 = atom->dihedral_atom4; int **nspecial = atom->nspecial; int nlocal = atom->nlocal; // stats on old 1-4 neighbor counts double onefourcount = 0.0; for (i = 0; i < nlocal; i++) onefourcount += nspecial[i][2]; double allcount; MPI_Allreduce(&onefourcount,&allcount,1,MPI_DOUBLE,MPI_SUM,world); if (me == 0) { if (screen) fprintf(screen, " %g = # of 1-4 neighbors before dihedral trim\n",allcount); if (logfile) fprintf(logfile, " %g = # of 1-4 neighbors before dihedral trim\n",allcount); } // if dihedrals are defined, flag each 1-4 neigh if it appears in a dihedral if (num_dihedral && atom->ndihedrals) { // dflag = flag for 1-4 neighs of all owned atoms int maxcount = 0; for (i = 0; i < nlocal; i++) maxcount = MAX(maxcount,nspecial[i][2]); memory->create(dflag,nlocal,maxcount,"special::dflag"); for (i = 0; i < nlocal; i++) { n = nspecial[i][2]; for (j = 0; j < n; j++) dflag[i][j] = 0; } // nbufmax = largest buffer needed to hold info from any proc // info for each atom = list of 1,4 atoms in each dihedral stored by atom int nbuf = 0; for (i = 0; i < nlocal; i++) nbuf += 2*num_dihedral[i]; int *buf; memory->create(buf,nbuf,"special:buf"); // fill buffer with list of 1,4 atoms in each dihedral int size = 0; for (i = 0; i < nlocal; i++) for (j = 0; j < num_dihedral[i]; j++) { buf[size++] = dihedral_atom1[i][j]; buf[size++] = dihedral_atom4[i][j]; } // cycle buffer around ring of procs back to self // when receive buffer, scan list of 1,4 atoms looking for atoms I own // when find one, scan its 1-4 neigh list and mark I,J as in a dihedral sptr = this; comm->ring(size,sizeof(tagint),buf,8,ring_eight,NULL); // delete 1-4 neighbors if they are not flagged in dflag for (i = 0; i < nlocal; i++) { m = 0; for (j = 0; j < nspecial[i][2]; j++) if (dflag[i][j]) onefour[i][m++] = onefour[i][j]; nspecial[i][2] = m; } // clean up memory->destroy(dflag); memory->destroy(buf); // if no dihedrals are defined, delete all 1-4 neighs } else { for (i = 0; i < nlocal; i++) nspecial[i][2] = 0; } // stats on new 1-4 neighbor counts onefourcount = 0.0; for (i = 0; i < nlocal; i++) onefourcount += nspecial[i][2]; MPI_Allreduce(&onefourcount,&allcount,1,MPI_DOUBLE,MPI_SUM,world); if (me == 0) { if (screen) fprintf(screen, " %g = # of 1-4 neighbors after dihedral trim\n",allcount); if (logfile) fprintf(logfile, " %g = # of 1-4 neighbors after dihedral trim\n",allcount); } } /* ---------------------------------------------------------------------- when receive buffer, scan tags for atoms I own when find one, increment nspecial count for that atom ------------------------------------------------------------------------- */ void Special::ring_one(int ndatum, char *cbuf) { Atom *atom = sptr->atom; int **nspecial = atom->nspecial; int nlocal = atom->nlocal; tagint *buf = (tagint *) cbuf; int m; for (int i = 0; i < ndatum; i++) { m = atom->map(buf[i]); if (m >= 0 && m < nlocal) nspecial[m][0]++; } } /* ---------------------------------------------------------------------- when receive buffer, scan 2nd-atom tags for atoms I own when find one, add 1st-atom tag to onetwo list for 2nd atom ------------------------------------------------------------------------- */ void Special::ring_two(int ndatum, char *cbuf) { Atom *atom = sptr->atom; int nlocal = atom->nlocal; tagint **onetwo = sptr->onetwo; int *count = sptr->count; tagint *buf = (tagint *) cbuf; int m; for (int i = 1; i < ndatum; i += 2) { m = atom->map(buf[i]); if (m >= 0 && m < nlocal) onetwo[m][count[m]++] = buf[i-1]; } } /* ---------------------------------------------------------------------- when receive buffer, scan list of 1-2 neighbors for atoms I own when find one, increment 1-3 count by # of 1-2 neighbors of my atom, subtracting one since my list will contain original atom ------------------------------------------------------------------------- */ void Special::ring_three(int ndatum, char *cbuf) { Atom *atom = sptr->atom; int **nspecial = atom->nspecial; int nlocal = atom->nlocal; tagint *buf = (tagint *) cbuf; int i,j,m,n,num12; i = 0; while (i < ndatum) { n = buf[i]; num12 = buf[i+1]; for (j = 0; j < num12; j++) { m = atom->map(buf[i+2+j]); if (m >= 0 && m < nlocal) n += nspecial[m][0] - 1; } buf[i] = n; i += 2 + num12; } } /* ---------------------------------------------------------------------- when receive buffer, scan list of 1-2 neighbors for atoms I own when find one, add its neighbors to 1-3 list increment the count in buf(i+4) exclude the atom whose tag = original this process may include duplicates but they will be culled later ------------------------------------------------------------------------- */ void Special::ring_four(int ndatum, char *cbuf) { Atom *atom = sptr->atom; int **nspecial = atom->nspecial; int nlocal = atom->nlocal; tagint **onetwo = sptr->onetwo; tagint *buf = (tagint *) cbuf; tagint original; int i,j,k,m,n,num12,num13; i = 0; while (i < ndatum) { original = buf[i]; num12 = buf[i+1]; num13 = buf[i+2]; n = buf[i+3]; for (j = 0; j < num12; j++) { m = atom->map(buf[i+4+j]); if (m >= 0 && m < nlocal) for (k = 0; k < nspecial[m][0]; k++) if (onetwo[m][k] != original) buf[i+4+num12+(n++)] = onetwo[m][k]; } buf[i+3] = n; i += 4 + num12 + num13; } } /* ---------------------------------------------------------------------- when receive buffer, scan list of 1-3 neighbors for atoms I own when find one, increment 1-4 count by # of 1-2 neighbors of my atom may include duplicates and original atom but they will be culled later ------------------------------------------------------------------------- */ void Special::ring_five(int ndatum, char *cbuf) { Atom *atom = sptr->atom; int **nspecial = atom->nspecial; int nlocal = atom->nlocal; tagint *buf = (tagint *) cbuf; int i,j,m,n,num13; i = 0; while (i < ndatum) { n = buf[i]; num13 = buf[i+1]; for (j = 0; j < num13; j++) { m = atom->map(buf[i+2+j]); if (m >= 0 && m < nlocal) n += nspecial[m][0]; } buf[i] = n; i += 2 + num13; } } /* ---------------------------------------------------------------------- when receive buffer, scan list of 1-3 neighbors for atoms I own when find one, add its neighbors to 1-4 list incrementing the count in buf(i+4) this process may include duplicates but they will be culled later ------------------------------------------------------------------------- */ void Special::ring_six(int ndatum, char *cbuf) { Atom *atom = sptr->atom; int **nspecial = atom->nspecial; int nlocal = atom->nlocal; tagint **onetwo = sptr->onetwo; tagint *buf = (tagint *) cbuf; int i,j,k,m,n,num13,num14; i = 0; while (i < ndatum) { num13 = buf[i]; num14 = buf[i+1]; n = buf[i+2]; for (j = 0; j < num13; j++) { m = atom->map(buf[i+3+j]); if (m >= 0 && m < nlocal) for (k = 0; k < nspecial[m][0]; k++) buf[i+3+num13+(n++)] = onetwo[m][k]; } buf[i+2] = n; i += 3 + num13 + num14; } } /* ---------------------------------------------------------------------- when receive buffer, scan list of 1,3 atoms looking for atoms I own when find one, scan its 1-3 neigh list and mark I,J as in an angle ------------------------------------------------------------------------- */ void Special::ring_seven(int ndatum, char *cbuf) { Atom *atom = sptr->atom; int **nspecial = atom->nspecial; int nlocal = atom->nlocal; tagint **onethree = sptr->onethree; int **dflag = sptr->dflag; tagint *buf = (tagint *) cbuf; tagint iglobal,jglobal; int i,m,ilocal,jlocal; i = 0; while (i < ndatum) { iglobal = buf[i]; jglobal = buf[i+1]; ilocal = atom->map(iglobal); jlocal = atom->map(jglobal); if (ilocal >= 0 && ilocal < nlocal) for (m = 0; m < nspecial[ilocal][1]; m++) if (jglobal == onethree[ilocal][m]) { dflag[ilocal][m] = 1; break; } if (jlocal >= 0 && jlocal < nlocal) for (m = 0; m < nspecial[jlocal][1]; m++) if (iglobal == onethree[jlocal][m]) { dflag[jlocal][m] = 1; break; } i += 2; } } /* ---------------------------------------------------------------------- when receive buffer, scan list of 1,4 atoms looking for atoms I own when find one, scan its 1-4 neigh list and mark I,J as in a dihedral ------------------------------------------------------------------------- */ void Special::ring_eight(int ndatum, char *cbuf) { Atom *atom = sptr->atom; int **nspecial = atom->nspecial; int nlocal = atom->nlocal; tagint **onefour = sptr->onefour; int **dflag = sptr->dflag; tagint *buf = (tagint *) cbuf; tagint iglobal,jglobal; int i,m,ilocal,jlocal; i = 0; while (i < ndatum) { iglobal = buf[i]; jglobal = buf[i+1]; ilocal = atom->map(iglobal); jlocal = atom->map(jglobal); if (ilocal >= 0 && ilocal < nlocal) for (m = 0; m < nspecial[ilocal][2]; m++) if (jglobal == onefour[ilocal][m]) { dflag[ilocal][m] = 1; break; } if (jlocal >= 0 && jlocal < nlocal) for (m = 0; m < nspecial[jlocal][2]; m++) if (iglobal == onefour[jlocal][m]) { dflag[jlocal][m] = 1; break; } i += 2; } } /* ---------------------------------------------------------------------- allow fixes to alter special list currently, only fix drude does this so that both the Drude core and electron are same level of neighbor ------------------------------------------------------------------------- */ void Special::fix_alteration() { for (int ifix = 0; ifix < modify->nfix; ifix++) if (modify->fix[ifix]->special_alter_flag) modify->fix[ifix]->rebuild_special(); } diff --git a/src/version.h b/src/version.h index 7f6864883..e24bd29bf 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "5 Oct 2016" +#define LAMMPS_VERSION "6 Oct 2016" diff --git a/tools/msi2lmp/README b/tools/msi2lmp/README index d6d48b387..a20f6e893 100644 --- a/tools/msi2lmp/README +++ b/tools/msi2lmp/README @@ -1,222 +1,227 @@ Axel Kohlmeyer is the current maintainer of the msi2lmp tool. Please send any inquiries about msi2lmp to the lammps-users mailing list. +06 Oct 2016 Axel Kohlmeyer + +Improved whitespace handling in parsing topology and force field +files to avoid bogus warnings about type name truncation. + 24 Oct 2015 Axel Kohlmeyer Added check to make certain that force field files are consistent with the notation of non-bonded parameters that the msi2lmp code expects. For Class 1 and OPLS-AA the A-B notation with geometric mixing is expected and for -Class 2 the r-eps notation with sixthpower mixing.( +Class 2 the r-eps notation with sixthpower mixing. 11 Sep 2014 Axel Kohlmeyer Refactored ReadMdfFile.c so it more consistently honors the MAX_NAME and MAX_STRING string length defines and potentially handles inputs with long names better. 27 May 2014 Axel Kohlmeyer Added TopoTools style type hints as comments to all Mass, PairCoeff, BondCoeff, AngleCoeff, DihedralCoeff, ImproperCoeff entries. This should make it easier to identify force field entries with the structure and force field map in the data file later. 06 Mar 2014 Axel Kohlmeyer Fixed a bug in handling of triclinic cells, where the matrices to convert to and from fractional coordinates were incorrectly built. 26 Oct 2013 Axel Kohlmeyer Implemented writing out force field style hints in generated data files for improved consistency checking when reading those files. Also added writing out CGCMM style comments to identify atom types. 08 Oct 2013 Axel Kohlmeyer Fixed a memory access violation with Class 2 force fields. Free all allocated memory to better detection of memory errors. Print out version number and data with all print levels > 0. Added valgrind checks to the regression tests 08 Oct 2013 Axel Kohlmeyer Fixed a memory access violation with Class 2 force fields. Free all allocated memory to better detection of memory errors. Print out version number and data with all print levels > 0. Added valgrind checks to the regression tests 02 Aug 2013 Axel Kohlmeyer Added rudimentary support for OPLS-AA based on input provided by jeff greathouse. 18 Jul 2013 Axel Kohlmeyer Added support for writing out image flags Improved accuracy of atom masses Added flag for shifting the entire system Fixed some minor logic bugs and prepared for supporting other force fields and morse style bonds. 12 Jul 2013 Axel Kohlmeyer Fixed the bug that caused improper coefficients to be wrong Cleaned up the handling of box parameters and center the box by default around the system/molecule. Added a flag to make this step optional and center the box around the origin instead. Added a regression test script with examples. 1 Jul 2013 Axel Kohlmeyer Cleanup and improved port to windows. Removed some more static string limits. Added print level 3 for additional output. Make code stop at missing force field parameters and added -i flag to override this. Safer argument checking. Provide short versions for all flags. 23 Sep 2011 added support for triclinic boxes see msi2lmp/TriclinicModification.pdf doc for details ----------------------------- msi2lmp V3.6 4/10/2005 This program uses the .car and .mdf files from MSI/Biosyms's INSIGHT program to produce a LAMMPS data file. 1. Building msi2lmp Use the Makefile in the src directory. It is currently set up for gcc. You will have to modify it to use a different compiler. 2. Testing the program There are several pairs of input test files in the format generated by materials studio or compatible programs (one .car and one .mdf file each) in the test directory. There is also a LAMMPS input to run a minimization for each and write out the resulting system as a data file. With the runtests.sh script all of those inputs are converted via msi2lmp, then the minimization with LAMMPS is run and the generated data files are compared with the corresponding files in the reference folder. This script assumes you are on a unix/linux system and that you have compile a serial LAMMPS executable called lmp_serial with make serial. The tests are groups by the force fields they use. 3. To run the program The program is started by supplying information at the command prompt according to the usage described below. USAGE: msi2lmp.exe {-print #} {-class #} {-frc FRC_FILE} {-ignore} {-nocenter} {-shift # # #} -- msi2lmp.exe is the name of the executable -- is the base name of the .car and .mdf files -- -2001 Output lammps files for LAMMPS version 2001 (F90 version) Default is to write output for the C++ version of LAMMPS -- -print (or -p) # is the print level 0 - silent except for error messages 1 - minimal (default) 2 - verbose (usual for developing and checking new data files for consistency) 3 - even more verbose (additional debug info) -- -ignore (or -i) ignore errors about missing force field parameters and treat them as warnings instead. -- -nocenter (or -n) do not recenter the simulation box around the geometrical center of the provided geometry but rather around the origin -- -oldstyle (or -o) write out a data file without style hints (to be compatible with older LAMMPS versions) -- -shift (or -s) translate the entire system (box and coordinates) by a vector (default: 0.0 0.0 0.0) -- -class (or -c) # is the class of forcefield to use (I or 1 = Class I e.g., CVFF) (O or 0 = OPLS-AA) (II or 2 = Class II e.g., CFFx) default is -class I -- -frc (or -f) specifies name of the forcefield file (e.g., cff91) If the file name includes a directory component (or drive letter on Windows), then the name is used as is. Otherwise, the program looks for the forcefield file in $MSI2LMP_LIBRARY (or %MSI2LMP_LIBRARY% on Windows). If $MSI2LMP_LIBRARY is not set, ../frc_files is used (for testing). If the file name does not end in .frc, then .frc is appended to the name. For example, -frc cvff (assumes cvff.frc is in $MSI2LMP_LIBRARY or ../frc_files) -frc cff/cff91 (assumes cff91.frc is in cff) -frc /usr/local/forcefields/cff95 (assumes cff95.frc is in /usr/local/forcefields/) By default, the program uses $MSI2LMP_LIBRARY/cvff.frc or ../frc_files/cvff.frc depending on whether MSI2LMP_LIBRARY is set. -- the LAMMPS data file is written to .data protocol and error information is written to the screen. **************************************************************** * * msi2lmp * * This is the third version of a program that generates a LAMMPS * data file based on the information in MSI .car (atom * coordinates), .mdf (molecular topology) and .frc (forcefield) * files. The .car and .mdf files are specific to a molecular * system while the .frc file is specific to a forcefield version. * The only coherency needed between .frc and .car/.mdf files are * the atom types. * * The first version was written by Steve Lustig at Dupont, but * required using Discover to derive internal coordinates and * forcefield parameters * * The second version was written by Michael Peachey while an * intern in the Cray Chemistry Applications Group managed * by John Carpenter. This version derived internal coordinates * from the mdf file and looked up parameters in the frc file * thus eliminating the need for Discover. * * The third version was written by John Carpenter to optimize * the performance of the program for large molecular systems * (the original code for deriving atom numbers was quadratic in time) * and to make the program fully dynamic. The second version used * fixed dimension arrays for the internal coordinates. * * The current maintainer is only reluctantly doing so because John Mayo no longer * needs this code. * * V3.2 corresponds to adding code to MakeLists.c to gracefully deal with * systems that may only be molecules of 1 to 3 atoms. In V3.1, the values * for number_of_dihedrals, etc. could be unpredictable in these systems. * * V3.3 was generated in response to a strange error reading a MDF file generated by * Accelys' Materials Studio GUI. Simply rewriting the input part of ReadMdfFile.c * seems to have fixed the problem. * * V3.4 and V3.5 are minor upgrades to fix bugs associated mostly with .car and .mdf files * written by Accelys' Materials Studio GUI. * * V3.6 outputs to LAMMPS 2005 (C++ version). * * Contact: Kelly L. Anderson, kelly.anderson@cantab.net * * April 2005 diff --git a/tools/msi2lmp/src/ReadMdfFile.c b/tools/msi2lmp/src/ReadMdfFile.c index 9bc820f37..0a0c240cf 100644 --- a/tools/msi2lmp/src/ReadMdfFile.c +++ b/tools/msi2lmp/src/ReadMdfFile.c @@ -1,422 +1,422 @@ /****************************** * * This function opens the .mdf file and extracts connectivity information * into the atoms Atom structure. It also updates the charge from the .car * file because the charge in the .mdf file has more significant figures. * */ #include "msi2lmp.h" #include #include #include /* Prototype for function to process a single atom Returns int that flags end of data file */ static int get_molecule(char line[], int connect_col_no, int q_col_no, int *counter); /* Prototype for function that takes connectivty record as stated in .mdf file and fills in any default values */ static void MakeConnectFullForm(int *counter); /* prototype for function to clean strange characters out of strings */ static void clean_string(char *); static int blank_line(char *line) { while (*line != '\0') { if (isalnum((int) *line)) return 0; ++line; } return 1; } void ReadMdfFile(void) { char line[MAX_LINE_LENGTH]; /* Temporary storage for reading lines */ char *col_no; /* Pointer to column number stored as char */ char *col_name; /* Pointer to column name */ int connect_col_no = 0; /* Column number where connection info begins */ int q_col_no = 0; /* Column number containg charge information */ int atom_counter=0; /* Keeps track of current atom number */ int i,j,k,kk,l,n,match,match2,status; char *temp_string; char *temp_residue; char *temp_atom_name; char *sptr; unsigned char at_end = 0; /* Open .mdf file for reading */ sprintf(line,"%s.mdf",rootname); if (pflag > 0) printf(" Reading mdf file: %s\n",line); if ((MdfF = fopen(line,"r")) == NULL ) { printf("Cannot open %s\n",line); exit(41); } while (!at_end) { sptr = fgets(line,MAX_LINE_LENGTH,MdfF); if (sptr != NULL) { clean_string(line); if (strncmp(line,"#end",4) == 0) { at_end = 1; } else if (strncmp(line,"@column",7) == 0) { - temp_string = strtok(line," "); - col_no = strtok(NULL," "); - col_name = strtok(NULL," "); + temp_string = strtok(line,WHITESPACE); + col_no = strtok(NULL,WHITESPACE); + col_name = strtok(NULL,WHITESPACE); if (strncmp(col_name,"charge",6) == 0) { if (strlen(col_name) < 8) { q_col_no = atoi(col_no); } } else if (strncmp(col_name,"connect",7) == 0) { connect_col_no = atoi(col_no); } } else if (strncmp(line,"@molecule",9) == 0) { if ((q_col_no == 0) | (connect_col_no == 0)) { printf("Unable to process molecule without knowing charge\n"); printf("and connections columns\n"); exit(42); } sptr = fgets(line,MAX_LINE_LENGTH,MdfF); status = get_molecule(line,connect_col_no,q_col_no,&atom_counter); if (status == 0) { printf("Trouble reading molecule - exiting\n"); exit(43); } } } else { printf("End of File found or error reading line\n"); at_end = 1; } } /* Next build list of residues for each molecule This will facilitate assigning connections numbers as well as figuring out bonds, angles, etc. This first loop just figures out the number of residues in each molecule and allocates memory to store information for each residue. The second loop fills in starting and ending atom positions for each residue */ temp_string = (char *)calloc(MAX_STRING,sizeof(char)); for (n=0; n < no_molecules; n++) { molecule[n].no_residues = 1; strncpy(temp_string,atoms[molecule[n].start].residue_string,MAX_NAME); for (i=molecule[n].start+1; i < molecule[n].end; i++) { if (strncmp(temp_string,atoms[i].residue_string,MAX_NAME) != 0) { molecule[n].no_residues++; strncpy(temp_string,atoms[i].residue_string,MAX_NAME); } } molecule[n].residue = (struct ResidueList *) calloc(molecule[n].no_residues, sizeof(struct ResidueList)); if (molecule[n].residue == NULL) { printf("Unable to allocate memory for residue list - molecule %d\n",n); exit(44); } } for (n=0; n < no_molecules; n++) { j = 0; strncpy(molecule[n].residue[j].name, atoms[molecule[n].start].residue_string,MAX_NAME); molecule[n].residue[j].start = molecule[n].start; for (i=molecule[n].start+1; i < molecule[n].end; i++) { if (strncmp(molecule[n].residue[j].name, atoms[i].residue_string,MAX_NAME) != 0) { molecule[n].residue[j].end = i; molecule[n].residue[++j].start = i; strncpy(molecule[n].residue[j].name,atoms[i].residue_string,MAX_NAME); } } molecule[n].residue[j].end = molecule[n].end; /* printf("Molecule %d has %d residues",n,molecule[n].no_residues); for (i=0; i < molecule[n].no_residues; i++) { printf(" %s",molecule[n].residue[i].name); } printf("\n"); for (i=molecule[n].start; i < molecule[n].end; i++) { printf(" atom %d residue %s\n",i,atoms[i].residue_string); } printf(" residue %s start %d end %d\n",molecule[n].residue[i].name, molecule[n].residue[i].start,molecule[n].residue[i].end); } */ } /* Assign atom names in connections[] to corresponding atom numbers */ for (n=0; n < no_molecules; n++) { for (j=0; j < molecule[n].no_residues; j++) { for (i=molecule[n].residue[j].start; i < molecule[n].residue[j].end; i++) { for (l=0; l < atoms[i].no_connect; l++) { strncpy(temp_string,atoms[i].connections[l],MAX_STRING); temp_residue = strtok(temp_string,":"); temp_atom_name = strtok(NULL,"%"); if (strcmp(temp_residue,molecule[n].residue[j].name) == 0) { /* atom and connection are part of same residue Search names on just that residue */ k = molecule[n].residue[j].start; match = 0; while (!match && (k < molecule[n].residue[j].end)) { if (strcmp(atoms[k].name,temp_atom_name) == 0) { atoms[i].conn_no[l] = k; match = 1; } else k++; } if (match == 0) { printf("Unable to resolve atom number of atom %d conn %d string %s:%s\n" " Something is wrong in the MDF file\n", i,l,temp_residue,temp_atom_name); exit(45); } } else { /* atom and connection are on different residues First find the residue that the connection is on then loop over its atoms */ k=0; match = 0; while (!match && (k < molecule[n].no_residues)) { if (strcmp(temp_residue,molecule[n].residue[k].name) == 0) { kk = molecule[n].residue[k].start; match2 = 0; while (!match2 && (kk < molecule[n].residue[k].end)) { if (strcmp(atoms[kk].name,temp_atom_name) == 0) { atoms[i].conn_no[l] = kk; match2 = 1; } else kk++; } if (match2 == 0) { printf("Unable to resolve atom number of atom %d conn %d string %s\n" " Something is wrong in the MDF file\n", i,l,atoms[i].connections[l]); exit(46); } match = 1; } else k++; } if (match == 0) { printf("Unable to find residue associated with conn %d %s on atom %d\n" " Something is wrong in the MDF file\n", l,atoms[i].connections[l],i); exit(47); } } /* end if */ } /* l - loop over connections on atom i */ } /* i - loop on atoms in residue j molecule n */ } /* j - loop on residues in molecule n */ } /* n - loop over molecules */ free(temp_string); /* for (n=0; n < no_molecules; n++) { printf("Molecule %d has %d residues\n",n,molecule[n].no_residues); for (j=0; j < molecule[n].no_residues; j++) { printf(" Residue %d named %s\n",j,molecule[n].residue[j].name); for (i=molecule[n].residue[j].start; i < molecule[n].residue[j].end; i++) { printf(" Atom %d type %s connected to ",i,atoms[i].potential); for (l=0; l < atoms[i].no_connect; l++) printf(" %d ", atoms[i].conn_no[l]); printf("\n"); } } } */ /* Close .mdf file */ if (fclose(MdfF) !=0) { printf("Error closing %s.car\n", rootname); exit(1); } } /* End ReadMdfFile function */ /*--------------------- get_molecule Function-----------------------*/ int get_molecule(char *line, int connect_col_no, int q_col_no, int *counter) { char *cur_field; /* For storing current string token */ int i; /* Used in loop counters */ int connect_no; /* Connection number within atom */ int r_val = 1; /* Return value. 1 = successful 0 = EOF encountered */ /* Loop over atoms */ /* blank line signals end of molecule*/ while(!blank_line(fgets(line,MAX_LINE_LENGTH,MdfF))) { /* while(strlen(fgets(line,MAX_LINE_LENGTH,MdfF)) > 2) { */ clean_string(line); /* Get atom name */ cur_field = strtok(line,":"); sscanf(cur_field, "%s", atoms[*counter].residue_string); - cur_field = strtok(NULL," "); + cur_field = strtok(NULL,WHITESPACE); /* Compare atom name with that in .car file */ if (strcmp(atoms[*counter].name, cur_field)) { printf("Names %s from .car file and %s from .mdf file do not match\n", atoms[*counter].name, cur_field); printf("counter = %d\n",*counter); printf("Program Terminating\n"); exit(4); } /* Skip unwanted fields until charge column, then update charge */ - for (i=1; i < q_col_no; i++) strtok(NULL," "); - cur_field = strtok(NULL, " "); + for (i=1; i < q_col_no; i++) strtok(NULL,WHITESPACE); + cur_field = strtok(NULL, WHITESPACE); atoms[*counter].q = atof(cur_field); /* Continue skipping unwanted fields until connectivity records begin */ - for ( i = (q_col_no + 1); i < connect_col_no; i++) strtok(NULL," "); + for ( i = (q_col_no + 1); i < connect_col_no; i++) strtok(NULL,WHITESPACE); /* Process connections */ connect_no = 0; /* reset connections counter */ - while ((cur_field = strtok(NULL," ")) && (connect_no < MAX_CONNECTIONS)) { + while ((cur_field = strtok(NULL,WHITESPACE)) && (connect_no < MAX_CONNECTIONS)) { sscanf(cur_field, "%s", atoms[*counter].connections[connect_no++]); } atoms[*counter].no_connect = connect_no; MakeConnectFullForm(counter); (*counter)++; } /* End atom processing loop */ return r_val; } /* End get_molecule function */ /*------------------------MakeConnectFullForm Function--------------------*/ void MakeConnectFullForm(int *counter) { /* This function processes the connection names after all connections for an atom have been read in. It replaces any short forms that use implied default values with the full form connectivity record */ int i; /* Counter for character array */ int j; /* loop counter */ char tempname[2*MAX_STRING]; /* name of connection */ char tempcell[10]; /* Values from connectivity record */ char tempsym[5]; /* " " */ char tempbo[6]; /* " " */ char *charptr; for ( j = 0; j < atoms[*counter].no_connect; j++) { /* If not full name, make name full */ if (strchr(atoms[*counter].connections[j],':') == NULL) { strcpy(tempname,atoms[*counter].residue_string); strcat(tempname,":"); strcat(tempname, atoms[*counter].connections[j]); /* truncate at capacity of target storage */ tempname[MAX_STRING-1] = '\0'; sscanf(tempname, "%s", atoms[*counter].connections[j]); } else sscanf(atoms[*counter].connections[j], "%s", tempname); /* Set cell variables */ i=0; charptr = (strchr(tempname,'%')); if (charptr != NULL) { while ( *charptr!='#' && *charptr!='/' && *charptr!='\000') tempcell[i++] = *(charptr++); tempcell[i] = '\000'; } else strcpy(tempcell, "%000"); /* Set symmetry variables -- If not 1, cannot handle at this time */ i = 0; charptr = (strchr(tempname,'#')); if (charptr != NULL) { while (*charptr != '/' && *charptr !='\000') { tempsym[i++] = *(charptr++); if ((i==2) && (tempsym[1] != '1')) { printf("Msi2LMP is not equipped to handle symmetry operations\n"); exit(5); } } tempsym[i] = '\000'; } else strcpy(tempsym, "#1"); /* Set bond order and record in data structure */ i = 0; charptr = strchr(tempname,'/'); if (charptr != NULL) { charptr++; while (*charptr != '\000') tempbo[i++] = *(charptr++); tempbo[i] = '\000'; } else strcpy(tempbo, "1.0"); atoms[*counter].bond_order[j] = atof(tempbo); /* Build connection name and store in atoms data structure */ strtok( tempname, "%#/"); strcat( tempname, tempcell); strcat( tempname, tempsym); strcat( tempname, "/"); strcat( tempname, tempbo); if (strlen(tempname) >= MAX_STRING) { printf("tempname overrun %s. truncating to ",tempname); /* truncate at capacity of target storage */ tempname[MAX_STRING-1] = '\0'; puts(tempname); } sscanf(tempname, "%s", atoms[*counter].connections[j]); }/*End for loop*/ }/* End function MakeNameLong */ void clean_string(char *string) { int i,n; short k; n = strlen(string); for (i=0; i < n; i++) { k = (short)string[i]; if ((k<32) | (k>127)) string[i] = '\0'; } } diff --git a/tools/msi2lmp/src/SearchAndFill.c b/tools/msi2lmp/src/SearchAndFill.c index a779dbcf3..1a85ee111 100644 --- a/tools/msi2lmp/src/SearchAndFill.c +++ b/tools/msi2lmp/src/SearchAndFill.c @@ -1,262 +1,262 @@ /**************************** * * This function first allocates memory to the forcefield item * structures and then reads parameters from the forcefield file into the * allocated memory * */ #include "msi2lmp.h" #include "Forcefield.h" #include #include #include static int blank_line(char *line) { while (*line != '\0') { if (isalnum((int) *line)) return 0; ++line; } return 1; } static unsigned char string_match(const char *,const char *); void ClearFrcItem(struct FrcFieldItem *item) { free(item->data); } const char *SearchAndCheck(const char *keyword) { char *status; int got_it = 0; char line[MAX_LINE_LENGTH] = "empty"; rewind(FrcF); while (got_it == 0) { status = fgets( line, MAX_LINE_LENGTH, FrcF ); if (status == NULL) { fprintf(stderr," Unable to find keyword '%s'\n",keyword); fprintf(stderr," Check consistency of forcefield name and class \n"); fprintf(stderr," Exiting....\n"); exit(1); } if (line[0] == '@') { - if (string_match(strtok(line+1," '\t\n'("),keyword)) { + if (string_match(strtok(line+1," '\t\n\r\f("),keyword)) { got_it = 1; - status = strtok(NULL," '\t\n("); + status = strtok(NULL," '\t\n\r\f("); if (status != NULL) return strdup(status); } } } return strdup("(unknown)"); } void SearchAndFill(struct FrcFieldItem *item) { int i,j; /* counters */ int got_it = 0; int ctr = 0; long file_pos; char line[MAX_LINE_LENGTH] = "empty"; char *charptr,*status; /***********************ALLOCATE MEMORY FOR STRUCTURE ********************/ /* Read and discard lines until keyword is found */ rewind(FrcF); while (got_it == 0) { status = fgets( line, MAX_LINE_LENGTH, FrcF ); if (status == NULL) { fprintf(stderr," Unable to find keyword '%s'\n",item->keyword); fprintf(stderr," Check consistency of forcefield name and class \n"); fprintf(stderr," Exiting....\n"); exit(1); } if (line[0] == '#') { - if (string_match(strtok(line," '\t'("),item->keyword)) got_it = 1; + if (string_match(strtok(line," '\t\r\n("),item->keyword)) got_it = 1; } /* if (strncmp(line, item->keyword,strlen(item->keyword))==0) got_it = 1; */ } file_pos = ftell(FrcF); /* Count the number of lines until next item is found */ while( strncmp(fgets(line,MAX_LINE_LENGTH,FrcF), "#", 1) != 0 ) ctr++; /* Allocate the memory using calloc */ item->data = (struct FrcFieldData *)calloc(ctr, sizeof(struct FrcFieldData)); if (item->data == NULL) { fprintf(stderr,"Could not allocate memory to %s\n", item->keyword); exit(2); } /********************FILL PARAMETERS AND EQUIVALENCES ********************/ /* Read lines until keyword is found */ fseek(FrcF,file_pos,SEEK_SET); strcpy(line,"empty"); /* Read lines until data starts (when !--- is found) */ ctr = 0; while ( strncmp(line,"!---", 4) != 0 ) { fgets(line, MAX_LINE_LENGTH, FrcF); } /* Get first line of data that isn't commented out */ fgets(line, MAX_LINE_LENGTH, FrcF); while (strncmp(line,"!",1) == 0) { fgets( line, MAX_LINE_LENGTH, FrcF); } /* Read data into structure */ while( strncmp( line, "#", 1 ) != 0 ) { float version; int reference,replace; char atom_types[5][5]; double parameters[8]; /* version number and reference number */ - version = atof(strtok(line, " ")); - reference = atoi(strtok(NULL, " ")); + version = atof(strtok(line, WHITESPACE)); + reference = atoi(strtok(NULL, WHITESPACE)); /* equivalences */ for(i = 0; i < item->number_of_members; i++ ) { - charptr = strtok(NULL, " "); + charptr = strtok(NULL, WHITESPACE); if (strlen(charptr) > 4) { fprintf(stderr,"Warning: type name overflow for '%s'. " "Truncating to 4 characters.\n",charptr); } sscanf(charptr,"%4s",atom_types[i]); } /* parameters -- Because of symmetrical terms, bonang, angtor, and endbontor have to be treated carefully */ for( i = 0; i < item->number_of_parameters; i++ ) { - charptr = strtok(NULL, " "); + charptr = strtok(NULL, WHITESPACE); if(charptr == NULL) { for ( j = i; j < item->number_of_parameters; j++ ) parameters[j] = parameters[j-i]; break; } else { parameters[i] = atof(charptr); } } /* Search for matching sets of atom types. If found and the version number is greater, substitute the current set of parameters in place of the found set. Otherwise, add the current set of parameters to the list. */ replace = ctr; for (j=0; j < ctr; j++) { int k=0; int match = 1; while (match && (k < item->number_of_members)) { if (strncmp(item->data[j].ff_types[k],atom_types[k],5) == 0) k++; else match = 0; } if (match == 1) { replace = j; break; } } if (replace != ctr) { if (version > item->data[replace].ver) { if (pflag > 1) { fprintf(stderr," Using higher version of parameters for"); fprintf(stderr," %s ",item->keyword); for (i=0; i < item->number_of_members; i++) fprintf(stderr,"%s ",atom_types[i]); fprintf(stderr," version %3.2f\n",version); } item->data[replace].ver = version; item->data[replace].ref = reference; for (i=0; i < item->number_of_members; i++) { strncpy(item->data[replace].ff_types[i],atom_types[i],5); } for (i=0; i < item->number_of_parameters; i++) { item->data[replace].ff_param[i] = parameters[i]; } } else { if (pflag > 1) { fprintf(stderr," Using higher version of parameters for"); fprintf(stderr," %s ",item->keyword); for (i=0; i < item->number_of_members; i++) fprintf(stderr,"%s ",item->data[replace].ff_types[i]); fprintf(stderr," version %3.2f\n",item->data[replace].ver); } } } else { item->data[ctr].ver = version; item->data[ctr].ref = reference; for (i=0; i < item->number_of_members; i++) { strncpy(item->data[ctr].ff_types[i],atom_types[i],5); } for (i=0; i < item->number_of_parameters; i++) { item->data[ctr].ff_param[i] = parameters[i]; } ctr++; } fgets( line, MAX_LINE_LENGTH, FrcF); /*if blank line encountered, get next */ while((blank_line(line)) || (strncmp(line,"!",1) == 0)) { status = fgets( line, MAX_LINE_LENGTH, FrcF); if (status == NULL) break; } } item->entries = ctr; /*Debugging fprintf(stderr,"\n%s\n", item->keyword); for(i=0;inumber_of_members;j++) fprintf(stderr,"%3s ", item->data[i].ff_equiv[j]); fprintf(stderr," "); for(j=0;jnumber_of_parameters;j++) fprintf(stderr,"%10.5f ",item->data[i].ff_param[j]); fprintf(stderr,"\n"); } */ } unsigned char string_match(const char *string1,const char *string2) { int len1,len2; len1 = strlen(string1); len2 = strlen(string2); if (len1 != len2) { return 0; } else { if (strncmp(string1,string2,len1) == 0) { return 1; } else { return 0; } } } diff --git a/tools/msi2lmp/src/msi2lmp.c b/tools/msi2lmp/src/msi2lmp.c index 4dc7464e1..c94d4b4d7 100644 --- a/tools/msi2lmp/src/msi2lmp.c +++ b/tools/msi2lmp/src/msi2lmp.c @@ -1,439 +1,442 @@ /* * * msi2lmp.exe * +* v3.9.8 AK- Improved whitespace handling in parsing topology and force +* field files to avoid bogus warnings about type name truncation +* * v3.9.7 AK- Add check to enforce that Class1/OPLS-AA use A-B parameter * conventions in force field file and Class2 us r-eps conventions * * v3.9.6 AK- Refactoring of MDF file parser with more consistent * handling of compile time constants MAX_NAME and MAX_STRING * * v3.9.5 AK- Add TopoTools style force field parameter type hints * * v3.9.4 AK- Make force field style hints optional with a flag * * v3.9.3 AK- Bugfix for triclinic cells. * * v3.9.2 AK- Support for writing out force field style hints * * v3.9.1 AK- Bugfix for Class2. Free allocated memory. Print version number. * * v3.9 AK - Rudimentary support for OPLS-AA * * v3.8 AK - Some refactoring and cleanup of global variables * - Bugfixes for argument parsing and improper definitions * - improved handling of box dimensions and image flags * - port to compiling on windows using MinGW * - more consistent print level handling * - more consistent handling of missing parameters * - Added a regression test script with examples. * * V3.7 STM - Added support for triclinic cells * * v3.6 KLA - Changes to output to either lammps 2001 (F90 version) or to * lammps 2005 (C++ version) * * v3.4 JEC - a number of minor changes due to way newline and EOF are generated * on Materials Studio generated .car and .mdf files as well as odd * behavior out of newer Linux IO libraries. ReadMdfFile was restructured * in the process. * * v3.1 JEC - changed IO interface to standard in/out, forcefield file * location can be indicated by environmental variable; added * printing options, consistency checks and forcefield * parameter versions sensitivity (highest one used) * * v3.0 JEC - program substantially rewritten to reduce execution time * and be 98 % dynamic in memory use (still fixed limits on * number of parameter types for different internal coordinate * sets) * * v2.0 MDP - got internal coordinate information from mdf file and * forcefield parameters from frc file thus eliminating * need for Discover * * V1.0 SL - original version. Used .car file and internal coordinate * information from Discover to produce LAMMPS data file. * * This program uses the .car and .mdf files from MSI/Biosyms's INSIGHT * program to produce a LAMMPS data file. * * The program is started by supplying information at the command prompt * according to the usage described below. * * USAGE: msi2lmp3 ROOTNAME {-print #} {-class #} {-frc FRC_FILE} {-ignore} {-nocenter} {-oldstyle} * * -- msi2lmp3 is the name of the executable * -- ROOTNAME is the base name of the .car and .mdf files * -- all opther flags are optional and can be abbreviated (e.g. -p instead of -print) * * -- -print * # is the print level: 0 - silent except for errors * 1 - minimal (default) * 2 - more verbose * 3 - even more verbose * -- -class * # is the class of forcefield to use (I or 1 = Class I e.g., CVFF, clayff) * (II or 2 = Class II e.g., CFFx, COMPASS) * (O or 0 = OPLS-AA) * default is -class I * * -- -ignore - tells msi2lmp to ignore warnings and errors and keep going * * -- -nocenter - tells msi2lmp to not center the box around the (geometrical) * center of the atoms, but around the origin * * -- -oldstyle - tells msi2lmp to write out a data file without style hints * (to be compatible with older LAMMPS versions) * * -- -shift - tells msi2lmp to shift the entire system (box and coordinates) * by a vector (default: 0.0 0.0 0.0) * * -- -frc - specifies name of the forcefield file (e.g., cff91) * * If the name includes a hard wired directory (i.e., if the name * starts with . or /), then the name is used alone. Otherwise, * the program looks for the forcefield file in $MSI2LMP_LIBRARY. * If $MSI2LMP_LIBRARY is not set, then the current directory is * used. * * If the file name does not include a dot after the first * character, then .frc is appended to the name. * * For example, -frc cvff (assumes cvff.frc is in $MSI2LMP_LIBRARY * or .) * * -frc cff/cff91 (assumes cff91.frc is in * $MSI2LMP_LIBRARY/cff or ./cff) * * -frc /usr/local/forcefields/cff95 (absolute * location) * * By default, the program uses $MSI2LMP_LIBRARY/cvff.frc * * -- output is written to a file called ROOTNAME.data * * **************************************************************** * * msi2lmp * * This is the third version of a program that generates a LAMMPS * data file based on the information in a MSI car file (atom * coordinates) and mdf file (molecular topology). A key part of * the program looks up forcefield parameters from an MSI frc file. * * The first version was written by Steve Lustig at Dupont, but * required using Discover to derive internal coordinates and * forcefield parameters * * The second version was written by Michael Peachey while an * in intern in the Cray Chemistry Applications Group managed * by John Carpenter. This version derived internal coordinates * from the mdf file and looked up parameters in the frc file * thus eliminating the need for Discover. * * The third version was written by John Carpenter to optimize * the performance of the program for large molecular systems * (the original code for deriving atom numbers was quadratic in time) * and to make the program fully dynamic. The second version used * fixed dimension arrays for the internal coordinates. * * John Carpenter can be contacted by sending email to * jec374@earthlink.net * * November 2000 */ #include "msi2lmp.h" #include #include #include /* global variables */ char *rootname; double pbc[6]; double box[3][3]; double shift[3]; int periodic = 1; int TriclinicFlag = 0; int forcefield = 0; int centerflag = 1; int hintflag = 1; int ljtypeflag = 0; int pflag; int iflag; int *no_atoms; int no_molecules; int replicate[3]; int total_no_atoms = 0; int total_no_bonds = 0; int total_no_angles = 0; int total_no_dihedrals = 0; int total_no_angle_angles = 0; int total_no_oops = 0; int no_atom_types = 0; int no_bond_types = 0; int no_angle_types = 0; int no_dihedral_types = 0; int no_oop_types = 0; int no_angleangle_types = 0; char *FrcFileName = NULL; FILE *CarF = NULL; FILE *FrcF = NULL; FILE *PrmF = NULL; FILE *MdfF = NULL; FILE *RptF = NULL; struct Atom *atoms = NULL; struct MoleculeList *molecule = NULL; struct BondList *bonds = NULL; struct AngleList *angles = NULL; struct DihedralList *dihedrals = NULL; struct OOPList *oops = NULL; struct AngleAngleList *angleangles = NULL; struct AtomTypeList *atomtypes = NULL; struct BondTypeList *bondtypes = NULL; struct AngleTypeList *angletypes = NULL; struct DihedralTypeList *dihedraltypes = NULL; struct OOPTypeList *ooptypes = NULL; struct AngleAngleTypeList *angleangletypes = NULL; void condexit(int val) { if (iflag == 0) exit(val); } static int check_arg(char **arg, const char *flag, int num, int argc) { if (num >= argc) { printf("Missing argument to \"%s\" flag\n",flag); return 1; } if (arg[num][0] == '-') { printf("Incorrect argument to \"%s\" flag: %s\n",flag,arg[num]); return 1; } return 0; } int main (int argc, char *argv[]) { int n,i,found_sep; const char *frc_dir_name = NULL; const char *frc_file_name = NULL; pflag = 1; iflag = 0; forcefield = FF_TYPE_CLASS1 | FF_TYPE_COMMON; shift[0] = shift[1] = shift[2] = 0.0; frc_dir_name = getenv("MSI2LMP_LIBRARY"); if (argc < 2) { printf("usage: %s [-class ] [-frc ] [-print #] [-ignore] [-nocenter] [-oldstyle]\n",argv[0]); return 1; } else { /* rootname was supplied as first argument, copy to rootname */ int len = strlen(argv[1]) + 1; rootname = (char *)malloc(len); strcpy(rootname,argv[1]); } n = 2; while (n < argc) { if (strncmp(argv[n],"-c",2) == 0) { n++; if (check_arg(argv,"-class",n,argc)) return 2; if ((strcmp(argv[n],"I") == 0) || (strcmp(argv[n],"1") == 0)) { forcefield = FF_TYPE_CLASS1 | FF_TYPE_COMMON; } else if ((strcmp(argv[n],"II") == 0) || (strcmp(argv[n],"2") == 0)) { forcefield = FF_TYPE_CLASS2 | FF_TYPE_COMMON; } else if ((strcmp(argv[n],"O") == 0) || (strcmp(argv[n],"0") == 0)) { forcefield = FF_TYPE_OPLSAA | FF_TYPE_COMMON; } else { printf("Unrecognized Forcefield class: %s\n",argv[n]); return 3; } } else if (strncmp(argv[n],"-f",2) == 0) { n++; if (check_arg(argv,"-frc",n,argc)) return 4; frc_file_name = argv[n]; } else if (strncmp(argv[n],"-s",2) == 0) { if (n+3 > argc) { printf("Missing argument(s) to \"-shift\" flag\n"); return 1; } shift[0] = atof(argv[++n]); shift[1] = atof(argv[++n]); shift[2] = atof(argv[++n]); } else if (strncmp(argv[n],"-i",2) == 0 ) { iflag = 1; } else if (strncmp(argv[n],"-n",4) == 0 ) { centerflag = 0; } else if (strncmp(argv[n],"-o",2) == 0 ) { hintflag = 0; } else if (strncmp(argv[n],"-p",2) == 0) { n++; if (check_arg(argv,"-print",n,argc)) return 5; pflag = atoi(argv[n]); } else { printf("Unrecognized option: %s\n",argv[n]); return 6; } n++; } /* set defaults, if nothing else was given */ if (frc_dir_name == NULL) #if (_WIN32) frc_dir_name = "..\\frc_files"; #else frc_dir_name = "../frc_files"; #endif if (frc_file_name == NULL) frc_file_name = "cvff.frc"; found_sep=0; #ifdef _WIN32 if (isalpha(frc_file_name[0]) && (frc_file_name[1] == ':')) found_sep=1; /* windows drive letter => full path. */ #endif n = strlen(frc_file_name); for (i=0; i < n; ++i) { #ifdef _WIN32 if ((frc_file_name[i] == '/') || (frc_file_name[i] == '\\')) found_sep=1+i; #else if (frc_file_name[i] == '/') found_sep=1+i; #endif } /* full pathname given */ if (found_sep) { i = 0; /* need to append extension? */ if ((n < 5) || (strcmp(frc_file_name+n-4,".frc") !=0)) i=1; FrcFileName = (char *)malloc(n+1+i*4); strcpy(FrcFileName,frc_file_name); if (i) strcat(FrcFileName,".frc"); } else { i = 0; /* need to append extension? */ if ((n < 5) || (strcmp(frc_file_name+n-4,".frc") !=0)) i=1; FrcFileName = (char *)malloc(n+2+i*4+strlen(frc_dir_name)); strcpy(FrcFileName,frc_dir_name); #ifdef _WIN32 strcat(FrcFileName,"\\"); #else strcat(FrcFileName,"/"); #endif strcat(FrcFileName,frc_file_name); if (i) strcat(FrcFileName,".frc"); } if (pflag > 0) { puts("\nRunning msi2lmp " MSI2LMP_VERSION "\n"); if (forcefield & FF_TYPE_CLASS1) puts(" Forcefield: Class I"); if (forcefield & FF_TYPE_CLASS2) puts(" Forcefield: Class II"); if (forcefield & FF_TYPE_OPLSAA) puts(" Forcefield: OPLS-AA"); printf(" Forcefield file name: %s\n",FrcFileName); if (centerflag) puts(" Output is recentered around geometrical center"); if (hintflag) puts(" Output contains style flag hints"); else puts(" Style flag hints disabled"); printf(" System translated by: %g %g %g\n",shift[0],shift[1],shift[2]); } n = 0; if (forcefield & FF_TYPE_CLASS1) { if (strstr(FrcFileName,"cvff") != NULL) ++n; if (strstr(FrcFileName,"clayff") != NULL) ++n; } else if (forcefield & FF_TYPE_OPLSAA) { if (strstr(FrcFileName,"oplsaa") != NULL) ++n; } else if (forcefield & FF_TYPE_CLASS2) { if (strstr(FrcFileName,"pcff") != NULL) ++n; if (strstr(FrcFileName,"cff91") != NULL) ++n; if (strstr(FrcFileName,"compass") != NULL) ++n; } if (n == 0) { if (iflag > 0) fputs(" WARNING",stderr); else fputs(" Error ",stderr); fputs("- forcefield name and class appear to be inconsistent\n\n",stderr); if (iflag == 0) return 7; } /* Read in .car file */ ReadCarFile(); /*Read in .mdf file */ ReadMdfFile(); /* Define bonds, angles, etc...*/ if (pflag > 0) printf("\n Building internal coordinate lists \n"); MakeLists(); /* Read .frc file into memory */ if (pflag > 0) printf("\n Reading forcefield file \n"); ReadFrcFile(); /* Get forcefield parameters */ if (pflag > 0) printf("\n Get force field parameters for this system\n"); GetParameters(); /* Do internal check of internal coordinate lists */ if (pflag > 0) printf("\n Check parameters for internal consistency\n"); CheckLists(); /* Write out the final data */ WriteDataFile(rootname); /* free up memory to detect possible memory corruption */ free(rootname); free(FrcFileName); ClearFrcData(); for (n=0; n < no_molecules; n++) { free(molecule[n].residue); } free(no_atoms); free(molecule); free(atoms); free(atomtypes); if (bonds) free(bonds); if (bondtypes) free(bondtypes); if (angles) free(angles); if (angletypes) free(angletypes); if (dihedrals) free(dihedrals); if (dihedraltypes) free(dihedraltypes); if (oops) free(oops); if (ooptypes) free(ooptypes); if (angleangles) free(angleangles); if (angleangletypes) free(angleangletypes); if (pflag > 0) printf("\nNormal program termination\n"); return 0; } diff --git a/tools/msi2lmp/src/msi2lmp.h b/tools/msi2lmp/src/msi2lmp.h index 9ef221a34..e07a4486d 100644 --- a/tools/msi2lmp/src/msi2lmp.h +++ b/tools/msi2lmp/src/msi2lmp.h @@ -1,226 +1,228 @@ /******************************** * * Header file for msi2lmp conversion program. * * This is the header file for the third version of a program * that generates a LAMMPS data file based on the information * in an MSI car file (atom coordinates) and mdf file (molecular * topology). A key part of the program looks up forcefield parameters * from an MSI frc file. * * The first version was written by Steve Lustig at Dupont, but * required using Discover to derive internal coordinates and * forcefield parameters * * The second version was written by Michael Peachey while an * intern in the Cray Chemistry Applications Group managed * by John Carpenter. This version derived internal coordinates * from the mdf file and looked up parameters in the frc file * thus eliminating the need for Discover. * * The third version was written by John Carpenter to optimize * the performance of the program for large molecular systems * (the original code for derving atom numbers was quadratic in time) * and to make the program fully dynamic. The second version used * fixed dimension arrays for the internal coordinates. * * The thrid version was revised in Fall 2011 by * Stephanie Teich-McGoldrick to add support non-orthogonal cells. * * The next revision was started in Summer/Fall 2013 by * Axel Kohlmeyer to improve portability to Windows compilers, * clean up command line parsing and improve compatibility with * the then current LAMMPS versions. This revision removes * compatibility with the obsolete LAMMPS version written in Fortran 90. */ # include -#define MSI2LMP_VERSION "v3.9.7 / 24 Oct 2015" +#define MSI2LMP_VERSION "v3.9.8 / 06 Oct 2016" #define PI_180 0.01745329251994329576 #define MAX_LINE_LENGTH 256 #define MAX_CONNECTIONS 8 #define MAX_STRING 64 #define MAX_NAME 16 +#define WHITESPACE " \t\r\n\f" + #define MAX_ATOM_TYPES 100 #define MAX_BOND_TYPES 200 #define MAX_ANGLE_TYPES 300 #define MAX_DIHEDRAL_TYPES 400 #define MAX_OOP_TYPES 400 #define MAX_ANGLEANGLE_TYPES 400 #define MAX_TYPES 12000 #define FF_TYPE_COMMON 1<<0 #define FF_TYPE_CLASS1 1<<1 #define FF_TYPE_CLASS2 1<<2 #define FF_TYPE_OPLSAA 1<<3 struct ResidueList { int start; int end; char name[MAX_NAME]; }; struct MoleculeList { int start; int end; int no_residues; struct ResidueList *residue; }; /* Internal coodinate Lists */ struct BondList { int type; int members[2]; }; struct AngleList { int type; int members[3]; }; struct DihedralList { int type; int members[4]; }; struct OOPList { int type; int members[4]; }; struct AngleAngleList { int type; int members[4]; }; /* Internal coodinate Types Lists */ struct AtomTypeList { char potential[5]; double mass; double params[2]; int no_connect; }; struct BondTypeList { int types[2]; double params[4]; }; struct AngleTypeList { int types[3]; double params[4]; double bondangle_cross_term[4]; double bondbond_cross_term[3]; }; struct DihedralTypeList { int types[4]; double params[6]; double endbonddihedral_cross_term[8]; double midbonddihedral_cross_term[4]; double angledihedral_cross_term[8]; double angleangledihedral_cross_term[3]; double bond13_cross_term[3]; }; struct OOPTypeList { int types[4]; double params[3]; double angleangle_params[6]; }; struct AngleAngleTypeList { int types[4]; double params[6]; }; /* ---------------------------------------------- */ struct Atom { int molecule; /* molecule id */ int no; /* atom id */ char name[MAX_NAME]; /* atom name */ double x[3]; /* position vector */ int image[3]; /* image flag */ char potential[6]; /* atom potential type */ char element[4]; /* atom element */ double q; /* charge */ char residue_string[MAX_NAME]; /* residue string */ int no_connect; /* number of connections to atom */ char connections[MAX_CONNECTIONS][MAX_STRING]; /* long form, connection name*/ double bond_order[MAX_CONNECTIONS]; int conn_no[MAX_CONNECTIONS]; /* Atom number to which atom is connected */ int type; }; extern char *rootname; extern char *FrcFileName; extern double pbc[6]; /* A, B, C, alpha, beta, gamma */ extern double box[3][3]; /* hi/lo for x/y/z and xy, xz, yz for triclinic */ extern double shift[3]; /* shift vector for all coordinates and box positions */ extern int periodic; /* 0= nonperiodic 1= 3-D periodic */ extern int TriclinicFlag; /* 0= Orthogonal 1= Triclinic */ extern int forcefield; /* BitMask: the value FF_TYPE_COMMON is set for common components of the options below, * FF_TYPE_CLASS1 = ClassI, FF_TYPE_CLASS2 = ClassII, FF_TYPE_OPLSAA = OPLS-AA*/ extern int ljtypeflag; /* how LJ paramters are stored: 0 = A-B, 1 = r-eps */ extern int centerflag; /* 1= center box 0= keep box */ extern int hintflag; /* 1= print style hint comments 0= no hints */ extern int pflag; /* print level: 0, 1, 2, 3 */ extern int iflag; /* 0 stop at errors 1 = ignore errors */ extern int *no_atoms; extern int no_molecules; extern int replicate[3]; extern int total_no_atoms; extern int total_no_bonds; extern int total_no_angles; extern int total_no_dihedrals; extern int total_no_angle_angles; extern int total_no_oops; extern int no_atom_types; extern int no_bond_types; extern int no_angle_types; extern int no_dihedral_types; extern int no_oop_types; extern int no_angleangle_types; extern FILE *CarF; extern FILE *FrcF; extern FILE *PrmF; extern FILE *MdfF; extern FILE *RptF; extern struct Atom *atoms; extern struct MoleculeList *molecule; extern struct BondList *bonds; extern struct AngleList *angles; extern struct DihedralList *dihedrals; extern struct OOPList *oops; extern struct AngleAngleList *angleangles; extern struct AtomTypeList *atomtypes; extern struct BondTypeList *bondtypes; extern struct AngleTypeList *angletypes; extern struct DihedralTypeList *dihedraltypes; extern struct OOPTypeList *ooptypes; extern struct AngleAngleTypeList *angleangletypes; extern void FrcMenu(); extern void ReadCarFile(); extern void ReadMdfFile(); extern void ReadFrcFile(); extern void ClearFrcData(); extern void MakeLists(); extern void GetParameters(); extern void CheckLists(); extern void WriteDataFile(char *); extern void set_box(double box[3][3], double *h, double *h_inv); extern void lamda2x(double *lamda, double *x, double *h, double *boxlo); extern void x2lamda(double *x, double *lamda, double *h_inv, double *boxlo); extern void condexit(int); diff --git a/tools/msi2lmp/test/reference/PyAC_bulk-clayff.data b/tools/msi2lmp/test/reference/PyAC_bulk-clayff.data index f53733b24..6b6602d69 100644 --- a/tools/msi2lmp/test/reference/PyAC_bulk-clayff.data +++ b/tools/msi2lmp/test/reference/PyAC_bulk-clayff.data @@ -1,1450 +1,1450 @@ -LAMMPS data file. msi2lmp v3.9.7 / 24 Oct 2015 / CGCMM for PyAC_bulk-clayff +LAMMPS data file. msi2lmp v3.9.8 / 06 Oct 2016 / CGCMM for PyAC_bulk-clayff 1280 atoms 128 bonds 0 angles 0 dihedrals 0 impropers 5 atom types 1 bond types -10.320000000 10.320000000 xlo xhi -17.931646038 17.931646038 ylo yhi -9.196614681 9.196614681 zlo zhi 0.225338675 -3.393877748 -0.363656523 xy xz yz Masses 1 26.981540 # ao 2 28.085500 # st 3 15.999400 # ob 4 15.999400 # oh 5 1.007970 # ho Pair Coeffs # lj/cut/coul/long 1 0.0000013297 4.2713219316 # ao 2 0.0000018402 3.3019566252 # st 3 0.1554164124 3.1655200879 # ob 4 0.1554164124 3.1655200879 # oh 5 0.0000000000 0.0000000000 # ho Bond Coeffs # harmonic 1 553.9350 1.0000 # oh-ho Atoms # full 1 1 1 1.575000 2.586827862 1.497292339 0.000000000 0 0 0 # ao 2 1 2 2.100000 3.405022262 8.885904024 2.679766593 0 0 0 # st 3 1 2 2.100000 3.441353082 2.867020152 2.686199476 0 0 0 # st 4 1 3 -1.050000 3.155524937 -0.004862688 1.061430252 0 0 0 # ob 5 1 3 -1.050000 3.594863921 2.739521172 1.064187192 0 0 0 # ob 6 1 4 -0.950000 0.995124606 1.708058368 0.993425143 0 0 0 # oh 7 1 3 -1.050000 -0.330143482 3.423343273 3.298245183 0 0 0 # ob 8 1 3 -1.050000 3.142554965 1.402537899 3.293650032 0 0 0 # ob 9 1 3 -1.050000 2.273933480 3.907815288 3.055632561 0 0 0 # ob 10 1 5 0.425000 2.086674864 1.701199854 1.194847627 0 0 0 # ho 11 1 1 1.575000 5.194995167 5.980203650 0.000000000 0 0 0 # ao 12 1 2 2.100000 0.796854958 4.402992713 2.679766593 0 0 0 # st 13 1 2 2.100000 0.889520539 7.349931463 2.686199476 0 0 0 # st 14 1 3 -1.050000 0.603692394 4.478048622 1.061430252 0 0 0 # ob 15 1 3 -1.050000 1.043031378 7.222432482 1.064187192 0 0 0 # ob 16 1 4 -0.950000 3.603291911 6.190969679 0.993425143 0 0 0 # oh 17 1 3 -1.050000 2.278023822 7.906254584 3.298245183 0 0 0 # ob 18 1 3 -1.050000 0.590722422 5.885449210 3.293650032 0 0 0 # ob 19 1 3 -1.050000 -0.277899062 8.390726598 3.055632561 0 0 0 # ob 20 1 5 0.425000 4.694842168 6.184111165 1.194847627 0 0 0 # ho 21 1 1 1.575000 2.629506747 7.468530282 0.000000000 0 0 0 # ao 22 1 2 2.100000 1.811312347 0.079918597 -2.679766593 0 0 0 # st 23 1 2 2.100000 1.774981527 6.098802469 -2.686199476 0 0 0 # st 24 1 3 -1.050000 2.060809673 8.970685310 -1.061430252 0 0 0 # ob 25 1 3 -1.050000 1.621470689 6.226301450 -1.064187192 0 0 0 # ob 26 1 4 -0.950000 4.221210003 7.257764253 -0.993425143 0 0 0 # oh 27 1 3 -1.050000 5.546478091 5.542479348 -3.298245183 0 0 0 # ob 28 1 3 -1.050000 2.073779644 7.563284723 -3.293650032 0 0 0 # ob 29 1 3 -1.050000 2.942401129 5.058007334 -3.055632561 0 0 0 # ob 30 1 5 0.425000 3.129659745 7.264622768 -1.194847627 0 0 0 # ho 31 1 1 1.575000 0.021339443 2.985618971 0.000000000 0 0 0 # ao 32 1 2 2.100000 4.419479652 4.562829908 -2.679766593 0 0 0 # st 33 1 2 2.100000 4.326814070 1.615891159 -2.686199476 0 0 0 # st 34 1 3 -1.050000 4.612642215 4.487773999 -1.061430252 0 0 0 # ob 35 1 3 -1.050000 4.173303231 1.743390139 -1.064187192 0 0 0 # ob 36 1 4 -0.950000 1.613042699 2.774852942 -0.993425143 0 0 0 # oh 37 1 3 -1.050000 2.938310787 1.059568038 -3.298245183 0 0 0 # ob 38 1 3 -1.050000 4.625612187 3.080373412 -3.293650032 0 0 0 # ob 39 1 3 -1.050000 5.494233672 0.575096023 -3.055632561 0 0 0 # ob 40 1 5 0.425000 0.521492441 2.781711457 -1.194847627 0 0 0 # ho 41 1 1 1.575000 7.746827709 1.497292339 0.000000000 0 0 0 # ao 42 1 2 2.100000 -12.074977890 8.885904024 2.679766593 1 0 0 # st 43 1 2 2.100000 -12.038647070 2.867020152 2.686199476 1 0 0 # st 44 1 3 -1.050000 8.315524784 -0.004862688 1.061430252 0 0 0 # ob 45 1 3 -1.050000 -11.885136232 2.739521172 1.064187192 1 0 0 # ob 46 1 4 -0.950000 6.155124454 1.708058368 0.993425143 0 0 0 # oh 47 1 3 -1.050000 4.829856365 3.423343273 3.298245183 0 0 0 # ob 48 1 3 -1.050000 -12.337445188 1.402537899 3.293650032 1 0 0 # ob 49 1 3 -1.050000 7.433933328 3.907815288 3.055632561 0 0 0 # ob 50 1 5 0.425000 7.246674711 1.701199854 1.194847627 0 0 0 # ho 51 1 1 1.575000 -10.285004986 5.980203650 0.000000000 1 0 0 # ao 52 1 2 2.100000 5.956854805 4.402992713 2.679766593 0 0 0 # st 53 1 2 2.100000 6.049520387 7.349931463 2.686199476 0 0 0 # st 54 1 3 -1.050000 5.763692241 4.478048622 1.061430252 0 0 0 # ob 55 1 3 -1.050000 6.203031225 7.222432482 1.064187192 0 0 0 # ob 56 1 4 -0.950000 -11.876708242 6.190969679 0.993425143 1 0 0 # oh 57 1 3 -1.050000 7.438023670 7.906254584 3.298245183 0 0 0 # ob 58 1 3 -1.050000 5.750722269 5.885449210 3.293650032 0 0 0 # ob 59 1 3 -1.050000 4.882100785 8.390726598 3.055632561 0 0 0 # ob 60 1 5 0.425000 -10.785157984 6.184111165 1.194847627 1 0 0 # ho 61 1 1 1.575000 7.789506595 7.468530282 0.000000000 0 0 0 # ao 62 1 2 2.100000 6.971312194 0.079918597 -2.679766593 0 0 0 # st 63 1 2 2.100000 6.934981375 6.098802469 -2.686199476 0 0 0 # st 64 1 3 -1.050000 7.220809520 8.970685310 -1.061430252 0 0 0 # ob 65 1 3 -1.050000 6.781470536 6.226301450 -1.064187192 0 0 0 # ob 66 1 4 -0.950000 -11.258790149 7.257764253 -0.993425143 1 0 0 # oh 67 1 3 -1.050000 -9.933522061 5.542479348 -3.298245183 1 0 0 # ob 68 1 3 -1.050000 7.233779492 7.563284723 -3.293650032 0 0 0 # ob 69 1 3 -1.050000 8.102400976 5.058007334 -3.055632561 0 0 0 # ob 70 1 5 0.425000 8.289659593 7.264622768 -1.194847627 0 0 0 # ho 71 1 1 1.575000 5.181339290 2.985618971 0.000000000 0 0 0 # ao 72 1 2 2.100000 -11.060520501 4.562829908 -2.679766593 1 0 0 # st 73 1 2 2.100000 -11.153186083 1.615891159 -2.686199476 1 0 0 # st 74 1 3 -1.050000 -10.867357937 4.487773999 -1.061430252 1 0 0 # ob 75 1 3 -1.050000 -11.306696921 1.743390139 -1.064187192 1 0 0 # ob 76 1 4 -0.950000 6.773042546 2.774852942 -0.993425143 0 0 0 # oh 77 1 3 -1.050000 8.098310634 1.059568038 -3.298245183 0 0 0 # ob 78 1 3 -1.050000 -10.854387965 3.080373412 -3.293650032 1 0 0 # ob 79 1 3 -1.050000 -9.985766481 0.575096023 -3.055632561 1 0 0 # ob 80 1 5 0.425000 5.681492288 2.781711457 -1.194847627 0 0 0 # ho 81 1 1 1.575000 -7.733172443 1.497292339 0.000000000 1 0 0 # ao 82 1 2 2.100000 -6.914978043 8.885904024 2.679766593 1 0 0 # st 83 1 2 2.100000 -6.878647223 2.867020152 2.686199476 1 0 0 # st 84 1 3 -1.050000 -7.164475369 -0.004862688 1.061430252 1 0 0 # ob 85 1 3 -1.050000 -6.725136384 2.739521172 1.064187192 1 0 0 # ob 86 1 4 -0.950000 -9.324875699 1.708058368 0.993425143 1 0 0 # oh 87 1 3 -1.050000 -10.650143787 3.423343273 3.298245183 1 0 0 # ob 88 1 3 -1.050000 -7.177445340 1.402537899 3.293650032 1 0 0 # ob 89 1 3 -1.050000 -8.046066825 3.907815288 3.055632561 1 0 0 # ob 90 1 5 0.425000 -8.233325441 1.701199854 1.194847627 1 0 0 # ho 91 1 1 1.575000 -5.125005139 5.980203650 0.000000000 1 0 0 # ao 92 1 2 2.100000 -9.523145348 4.402992713 2.679766593 1 0 0 # st 93 1 2 2.100000 -9.430479766 7.349931463 2.686199476 1 0 0 # st 94 1 3 -1.050000 -9.716307911 4.478048622 1.061430252 1 0 0 # ob 95 1 3 -1.050000 -9.276968927 7.222432482 1.064187192 1 0 0 # ob 96 1 4 -0.950000 -6.716708394 6.190969679 0.993425143 1 0 0 # oh 97 1 3 -1.050000 -8.041976483 7.906254584 3.298245183 1 0 0 # ob 98 1 3 -1.050000 -9.729277883 5.885449210 3.293650032 1 0 0 # ob 99 1 3 -1.050000 -10.597899368 8.390726598 3.055632561 1 0 0 # ob 100 1 5 0.425000 -5.625158137 6.184111165 1.194847627 1 0 0 # ho 101 1 1 1.575000 -7.690493558 7.468530282 0.000000000 1 0 0 # ao 102 1 2 2.100000 -8.508687958 0.079918597 -2.679766593 1 0 0 # st 103 1 2 2.100000 -8.545018778 6.098802469 -2.686199476 1 0 0 # st 104 1 3 -1.050000 -8.259190633 8.970685310 -1.061430252 1 0 0 # ob 105 1 3 -1.050000 -8.698529617 6.226301450 -1.064187192 1 0 0 # ob 106 1 4 -0.950000 -6.098790302 7.257764253 -0.993425143 1 0 0 # oh 107 1 3 -1.050000 -4.773522214 5.542479348 -3.298245183 1 0 0 # ob 108 1 3 -1.050000 -8.246220661 7.563284723 -3.293650032 1 0 0 # ob 109 1 3 -1.050000 -7.377599176 5.058007334 -3.055632561 1 0 0 # ob 110 1 5 0.425000 -7.190340560 7.264622768 -1.194847627 1 0 0 # ho 111 1 1 1.575000 -10.298660863 2.985618971 0.000000000 1 0 0 # ao 112 1 2 2.100000 -5.900520654 4.562829908 -2.679766593 1 0 0 # st 113 1 2 2.100000 -5.993186235 1.615891159 -2.686199476 1 0 0 # st 114 1 3 -1.050000 -5.707358090 4.487773999 -1.061430252 1 0 0 # ob 115 1 3 -1.050000 -6.146697074 1.743390139 -1.064187192 1 0 0 # ob 116 1 4 -0.950000 -8.706957607 2.774852942 -0.993425143 1 0 0 # oh 117 1 3 -1.050000 -7.381689518 1.059568038 -3.298245183 1 0 0 # ob 118 1 3 -1.050000 -5.694388118 3.080373412 -3.293650032 1 0 0 # ob 119 1 3 -1.050000 -4.825766634 0.575096023 -3.055632561 1 0 0 # ob 120 1 5 0.425000 -9.798507864 2.781711457 -1.194847627 1 0 0 # ho 121 1 1 1.575000 -2.573172596 1.497292339 0.000000000 1 0 0 # ao 122 1 2 2.100000 -1.754978196 8.885904024 2.679766593 1 0 0 # st 123 1 2 2.100000 -1.718647376 2.867020152 2.686199476 1 0 0 # st 124 1 3 -1.050000 -2.004475521 -0.004862688 1.061430252 1 0 0 # ob 125 1 3 -1.050000 -1.565136537 2.739521172 1.064187192 1 0 0 # ob 126 1 4 -0.950000 -4.164875852 1.708058368 0.993425143 1 0 0 # oh 127 1 3 -1.050000 -5.490143940 3.423343273 3.298245183 1 0 0 # ob 128 1 3 -1.050000 -2.017445493 1.402537899 3.293650032 1 0 0 # ob 129 1 3 -1.050000 -2.886066977 3.907815288 3.055632561 1 0 0 # ob 130 1 5 0.425000 -3.073325594 1.701199854 1.194847627 1 0 0 # ho 131 1 1 1.575000 0.034994709 5.980203650 0.000000000 1 0 0 # ao 132 1 2 2.100000 -4.363145500 4.402992713 2.679766593 1 0 0 # st 133 1 2 2.100000 -4.270479918 7.349931463 2.686199476 1 0 0 # st 134 1 3 -1.050000 -4.556308064 4.478048622 1.061430252 1 0 0 # ob 135 1 3 -1.050000 -4.116969080 7.222432482 1.064187192 1 0 0 # ob 136 1 4 -0.950000 -1.556708547 6.190969679 0.993425143 1 0 0 # oh 137 1 3 -1.050000 -2.881976635 7.906254584 3.298245183 1 0 0 # ob 138 1 3 -1.050000 -4.569278036 5.885449210 3.293650032 1 0 0 # ob 139 1 3 -1.050000 -5.437899520 8.390726598 3.055632561 1 0 0 # ob 140 1 5 0.425000 -0.465158289 6.184111165 1.194847627 1 0 0 # ho 141 1 1 1.575000 -2.530493711 7.468530282 0.000000000 1 0 0 # ao 142 1 2 2.100000 -3.348688111 0.079918597 -2.679766593 1 0 0 # st 143 1 2 2.100000 -3.385018931 6.098802469 -2.686199476 1 0 0 # st 144 1 3 -1.050000 -3.099190785 8.970685310 -1.061430252 1 0 0 # ob 145 1 3 -1.050000 -3.538529769 6.226301450 -1.064187192 1 0 0 # ob 146 1 4 -0.950000 -0.938790455 7.257764253 -0.993425143 1 0 0 # oh 147 1 3 -1.050000 0.386477634 5.542479348 -3.298245183 1 0 0 # ob 148 1 3 -1.050000 -3.086220813 7.563284723 -3.293650032 1 0 0 # ob 149 1 3 -1.050000 -2.217599329 5.058007334 -3.055632561 1 0 0 # ob 150 1 5 0.425000 -2.030340712 7.264622768 -1.194847627 1 0 0 # ho 151 1 1 1.575000 -5.138661015 2.985618971 0.000000000 1 0 0 # ao 152 1 2 2.100000 -0.740520806 4.562829908 -2.679766593 1 0 0 # st 153 1 2 2.100000 -0.833186388 1.615891159 -2.686199476 1 0 0 # st 154 1 3 -1.050000 -0.547358242 4.487773999 -1.061430252 1 0 0 # ob 155 1 3 -1.050000 -0.986697226 1.743390139 -1.064187192 1 0 0 # ob 156 1 4 -0.950000 -3.546957759 2.774852942 -0.993425143 1 0 0 # oh 157 1 3 -1.050000 -2.221689671 1.059568038 -3.298245183 1 0 0 # ob 158 1 3 -1.050000 -0.534388271 3.080373412 -3.293650032 1 0 0 # ob 159 1 3 -1.050000 0.334233214 0.575096023 -3.055632561 1 0 0 # ob 160 1 5 0.425000 -4.638508017 2.781711457 -1.194847627 1 0 0 # ho 161 1 1 1.575000 2.643162624 10.463114961 0.000000000 0 0 0 # ao 162 1 2 2.100000 3.236018349 -18.011565429 2.679766593 0 1 0 # st 163 1 2 2.100000 3.497687844 11.832842774 2.686199476 0 0 0 # st 164 1 3 -1.050000 3.211859698 8.960959933 1.061430252 0 0 0 # ob 165 1 3 -1.050000 3.651198683 11.705343793 1.064187192 0 0 0 # ob 166 1 4 -0.950000 1.051459368 10.673880990 0.993425143 0 0 0 # oh 167 1 3 -1.050000 -0.273808720 12.389165895 3.298245183 0 0 0 # ob 168 1 3 -1.050000 3.198889727 10.368360521 3.293650032 0 0 0 # ob 169 1 3 -1.050000 2.330268242 12.873637909 3.055632561 0 0 0 # ob 170 1 5 0.425000 2.143009626 10.667022476 1.194847627 0 0 0 # ho 171 1 1 1.575000 5.251329928 14.946026272 0.000000000 0 0 0 # ao 172 1 2 2.100000 0.853189719 13.368815335 2.679766593 0 0 0 # st 173 1 2 2.100000 0.945855301 16.315754084 2.686199476 0 0 0 # st 174 1 3 -1.050000 0.660027156 13.443871244 1.061430252 0 0 0 # ob 175 1 3 -1.050000 1.099366140 16.188255104 1.064187192 0 0 0 # ob 176 1 4 -0.950000 3.659626673 15.156792301 0.993425143 0 0 0 # oh 177 1 3 -1.050000 2.334358584 16.872077205 3.298245183 0 0 0 # ob 178 1 3 -1.050000 0.647057184 14.851271831 3.293650032 0 0 0 # ob 179 1 3 -1.050000 -0.221564301 17.356549220 3.055632561 0 0 0 # ob 180 1 5 0.425000 4.751176930 15.149933786 1.194847627 0 0 0 # ho 181 1 1 1.575000 2.685841509 16.434352904 0.000000000 0 0 0 # ao 182 1 2 2.100000 1.867647109 9.045741219 -2.679766593 0 0 0 # st 183 1 2 2.100000 1.831316289 15.064625091 -2.686199476 0 0 0 # st 184 1 3 -1.050000 1.891805759 -17.926784144 -1.061430252 0 1 0 # ob 185 1 3 -1.050000 1.677805450 15.192124071 -1.064187192 0 0 0 # ob 186 1 4 -0.950000 4.277544765 16.223586875 -0.993425143 0 0 0 # oh 187 1 3 -1.050000 5.602812853 14.508301970 -3.298245183 0 0 0 # ob 188 1 3 -1.050000 2.130114406 16.529107344 -3.293650032 0 0 0 # ob 189 1 3 -1.050000 2.998735891 14.023829955 -3.055632561 0 0 0 # ob 190 1 5 0.425000 3.185994507 16.230445389 -1.194847627 0 0 0 # ho 191 1 1 1.575000 0.077674204 11.951441593 0.000000000 0 0 0 # ao 192 1 2 2.100000 4.475814413 13.528652530 -2.679766593 0 0 0 # st 193 1 2 2.100000 4.383148832 10.581713780 -2.686199476 0 0 0 # st 194 1 3 -1.050000 4.668976977 13.453596621 -1.061430252 0 0 0 # ob 195 1 3 -1.050000 4.229637993 10.709212761 -1.064187192 0 0 0 # ob 196 1 4 -0.950000 1.669377460 11.740675564 -0.993425143 0 0 0 # oh 197 1 3 -1.050000 2.994645549 10.025390659 -3.298245183 0 0 0 # ob 198 1 3 -1.050000 4.681946949 12.046196033 -3.293650032 0 0 0 # ob 199 1 3 -1.050000 5.550568433 9.540918645 -3.055632561 0 0 0 # ob 200 1 5 0.425000 0.577827203 11.747534078 -1.194847627 0 0 0 # ho 201 1 1 1.575000 7.803162471 10.463114961 0.000000000 0 0 0 # ao 202 1 2 2.100000 -12.243981804 -18.011565429 2.679766593 1 1 0 # st 203 1 2 2.100000 -11.982312309 11.832842774 2.686199476 1 0 0 # st 204 1 3 -1.050000 8.371859546 8.960959933 1.061430252 0 0 0 # ob 205 1 3 -1.050000 -11.828801470 11.705343793 1.064187192 1 0 0 # ob 206 1 4 -0.950000 6.211459215 10.673880990 0.993425143 0 0 0 # oh 207 1 3 -1.050000 4.886191127 12.389165895 3.298245183 0 0 0 # ob 208 1 3 -1.050000 -12.281110426 10.368360521 3.293650032 1 0 0 # ob 209 1 3 -1.050000 7.490268090 12.873637909 3.055632561 0 0 0 # ob 210 1 5 0.425000 7.303009473 10.667022476 1.194847627 0 0 0 # ho 211 1 1 1.575000 -10.228670224 14.946026272 0.000000000 1 0 0 # ao 212 1 2 2.100000 6.013189567 13.368815335 2.679766593 0 0 0 # st 213 1 2 2.100000 6.105855149 16.315754084 2.686199476 0 0 0 # st 214 1 3 -1.050000 5.820027003 13.443871244 1.061430252 0 0 0 # ob 215 1 3 -1.050000 6.259365987 16.188255104 1.064187192 0 0 0 # ob 216 1 4 -0.950000 -11.820373480 15.156792301 0.993425143 1 0 0 # oh 217 1 3 -1.050000 7.494358432 16.872077205 3.298245183 0 0 0 # ob 218 1 3 -1.050000 5.807057031 14.851271831 3.293650032 0 0 0 # ob 219 1 3 -1.050000 4.938435547 17.356549220 3.055632561 0 0 0 # ob 220 1 5 0.425000 -10.728823222 15.149933786 1.194847627 1 0 0 # ho 221 1 1 1.575000 7.845841356 16.434352904 0.000000000 0 0 0 # ao 222 1 2 2.100000 7.027646956 9.045741219 -2.679766593 0 0 0 # st 223 1 2 2.100000 6.991316136 15.064625091 -2.686199476 0 0 0 # st 224 1 3 -1.050000 7.051805607 -17.926784144 -1.061430252 0 1 0 # ob 225 1 3 -1.050000 6.837805298 15.192124071 -1.064187192 0 0 0 # ob 226 1 4 -0.950000 -11.202455388 16.223586875 -0.993425143 1 0 0 # oh 227 1 3 -1.050000 -9.877187299 14.508301970 -3.298245183 1 0 0 # ob 228 1 3 -1.050000 7.290114254 16.529107344 -3.293650032 0 0 0 # ob 229 1 3 -1.050000 8.158735738 14.023829955 -3.055632561 0 0 0 # ob 230 1 5 0.425000 8.345994355 16.230445389 -1.194847627 0 0 0 # ho 231 1 1 1.575000 5.237674052 11.951441593 0.000000000 0 0 0 # ao 232 1 2 2.100000 -11.004185739 13.528652530 -2.679766593 1 0 0 # st 233 1 2 2.100000 -11.096851321 10.581713780 -2.686199476 1 0 0 # st 234 1 3 -1.050000 -10.811023175 13.453596621 -1.061430252 1 0 0 # ob 235 1 3 -1.050000 -11.250362159 10.709212761 -1.064187192 1 0 0 # ob 236 1 4 -0.950000 6.829377308 11.740675564 -0.993425143 0 0 0 # oh 237 1 3 -1.050000 8.154645396 10.025390659 -3.298245183 0 0 0 # ob 238 1 3 -1.050000 -10.798053204 12.046196033 -3.293650032 1 0 0 # ob 239 1 3 -1.050000 -9.929431719 9.540918645 -3.055632561 1 0 0 # ob 240 1 5 0.425000 5.737827050 11.747534078 -1.194847627 0 0 0 # ho 241 1 1 1.575000 -7.676837681 10.463114961 0.000000000 1 0 0 # ao 242 1 2 2.100000 -7.083981956 -18.011565429 2.679766593 1 1 0 # st 243 1 2 2.100000 -6.822312461 11.832842774 2.686199476 1 0 0 # st 244 1 3 -1.050000 -7.108140607 8.960959933 1.061430252 1 0 0 # ob 245 1 3 -1.050000 -6.668801623 11.705343793 1.064187192 1 0 0 # ob 246 1 4 -0.950000 -9.268540937 10.673880990 0.993425143 1 0 0 # oh 247 1 3 -1.050000 -10.593809026 12.389165895 3.298245183 1 0 0 # ob 248 1 3 -1.050000 -7.121110579 10.368360521 3.293650032 1 0 0 # ob 249 1 3 -1.050000 -7.989732063 12.873637909 3.055632561 1 0 0 # ob 250 1 5 0.425000 -8.176990680 10.667022476 1.194847627 1 0 0 # ho 251 1 1 1.575000 -5.068670377 14.946026272 0.000000000 1 0 0 # ao 252 1 2 2.100000 -9.466810586 13.368815335 2.679766593 1 0 0 # st 253 1 2 2.100000 -9.374145004 16.315754084 2.686199476 1 0 0 # st 254 1 3 -1.050000 -9.659973150 13.443871244 1.061430252 1 0 0 # ob 255 1 3 -1.050000 -9.220634165 16.188255104 1.064187192 1 0 0 # ob 256 1 4 -0.950000 -6.660373633 15.156792301 0.993425143 1 0 0 # oh 257 1 3 -1.050000 -7.985641721 16.872077205 3.298245183 1 0 0 # ob 258 1 3 -1.050000 -9.672943121 14.851271831 3.293650032 1 0 0 # ob 259 1 3 -1.050000 -10.541564606 17.356549220 3.055632561 1 0 0 # ob 260 1 5 0.425000 -5.568823375 15.149933786 1.194847627 1 0 0 # ho 261 1 1 1.575000 -7.634158796 16.434352904 0.000000000 1 0 0 # ao 262 1 2 2.100000 -8.452353196 9.045741219 -2.679766593 1 0 0 # st 263 1 2 2.100000 -8.488684016 15.064625091 -2.686199476 1 0 0 # st 264 1 3 -1.050000 -8.428194546 -17.926784144 -1.061430252 1 1 0 # ob 265 1 3 -1.050000 -8.642194855 15.192124071 -1.064187192 1 0 0 # ob 266 1 4 -0.950000 -6.042455540 16.223586875 -0.993425143 1 0 0 # oh 267 1 3 -1.050000 -4.717187452 14.508301970 -3.298245183 1 0 0 # ob 268 1 3 -1.050000 -8.189885899 16.529107344 -3.293650032 1 0 0 # ob 269 1 3 -1.050000 -7.321264415 14.023829955 -3.055632561 1 0 0 # ob 270 1 5 0.425000 -7.134005798 16.230445389 -1.194847627 1 0 0 # ho 271 1 1 1.575000 -10.242326101 11.951441593 0.000000000 1 0 0 # ao 272 1 2 2.100000 -5.844185892 13.528652530 -2.679766593 1 0 0 # st 273 1 2 2.100000 -5.936851473 10.581713780 -2.686199476 1 0 0 # st 274 1 3 -1.050000 -5.651023328 13.453596621 -1.061430252 1 0 0 # ob 275 1 3 -1.050000 -6.090362312 10.709212761 -1.064187192 1 0 0 # ob 276 1 4 -0.950000 -8.650622845 11.740675564 -0.993425143 1 0 0 # oh 277 1 3 -1.050000 -7.325354757 10.025390659 -3.298245183 1 0 0 # ob 278 1 3 -1.050000 -5.638053356 12.046196033 -3.293650032 1 0 0 # ob 279 1 3 -1.050000 -4.769431872 9.540918645 -3.055632561 1 0 0 # ob 280 1 5 0.425000 -9.742173103 11.747534078 -1.194847627 1 0 0 # ho 281 1 1 1.575000 -2.516837834 10.463114961 0.000000000 1 0 0 # ao 282 1 2 2.100000 -1.923982109 -18.011565429 2.679766593 1 1 0 # st 283 1 2 2.100000 -1.662312614 11.832842774 2.686199476 1 0 0 # st 284 1 3 -1.050000 -1.948140759 8.960959933 1.061430252 1 0 0 # ob 285 1 3 -1.050000 -1.508801775 11.705343793 1.064187192 1 0 0 # ob 286 1 4 -0.950000 -4.108541090 10.673880990 0.993425143 1 0 0 # oh 287 1 3 -1.050000 -5.433809178 12.389165895 3.298245183 1 0 0 # ob 288 1 3 -1.050000 -1.961110731 10.368360521 3.293650032 1 0 0 # ob 289 1 3 -1.050000 -2.829732216 12.873637909 3.055632561 1 0 0 # ob 290 1 5 0.425000 -3.016990832 10.667022476 1.194847627 1 0 0 # ho 291 1 1 1.575000 0.091329471 14.946026272 0.000000000 1 0 0 # ao 292 1 2 2.100000 -4.306810738 13.368815335 2.679766593 1 0 0 # st 293 1 2 2.100000 -4.214145157 16.315754084 2.686199476 1 0 0 # st 294 1 3 -1.050000 -4.499973302 13.443871244 1.061430252 1 0 0 # ob 295 1 3 -1.050000 -4.060634318 16.188255104 1.064187192 1 0 0 # ob 296 1 4 -0.950000 -1.500373785 15.156792301 0.993425143 1 0 0 # oh 297 1 3 -1.050000 -2.825641874 16.872077205 3.298245183 1 0 0 # ob 298 1 3 -1.050000 -4.512943274 14.851271831 3.293650032 1 0 0 # ob 299 1 3 -1.050000 -5.381564758 17.356549220 3.055632561 1 0 0 # ob 300 1 5 0.425000 -0.408823528 15.149933786 1.194847627 1 0 0 # ho 301 1 1 1.575000 -2.474158949 16.434352904 0.000000000 1 0 0 # ao 302 1 2 2.100000 -3.292353349 9.045741219 -2.679766593 1 0 0 # st 303 1 2 2.100000 -3.328684169 15.064625091 -2.686199476 1 0 0 # st 304 1 3 -1.050000 -3.268194698 -17.926784144 -1.061430252 1 1 0 # ob 305 1 3 -1.050000 -3.482195007 15.192124071 -1.064187192 1 0 0 # ob 306 1 4 -0.950000 -0.882455693 16.223586875 -0.993425143 1 0 0 # oh 307 1 3 -1.050000 0.442812395 14.508301970 -3.298245183 1 0 0 # ob 308 1 3 -1.050000 -3.029886052 16.529107344 -3.293650032 1 0 0 # ob 309 1 3 -1.050000 -2.161264567 14.023829955 -3.055632561 1 0 0 # ob 310 1 5 0.425000 -1.974005950 16.230445389 -1.194847627 1 0 0 # ho 311 1 1 1.575000 -5.082326253 11.951441593 0.000000000 1 0 0 # ao 312 1 2 2.100000 -0.684186044 13.528652530 -2.679766593 1 0 0 # st 313 1 2 2.100000 -0.776851626 10.581713780 -2.686199476 1 0 0 # st 314 1 3 -1.050000 -0.491023481 13.453596621 -1.061430252 1 0 0 # ob 315 1 3 -1.050000 -0.930362465 10.709212761 -1.064187192 1 0 0 # ob 316 1 4 -0.950000 -3.490622997 11.740675564 -0.993425143 1 0 0 # oh 317 1 3 -1.050000 -2.165354909 10.025390659 -3.298245183 1 0 0 # ob 318 1 3 -1.050000 -0.478053509 12.046196033 -3.293650032 1 0 0 # ob 319 1 3 -1.050000 0.390567976 9.540918645 -3.055632561 1 0 0 # ob 320 1 5 0.425000 -4.582173255 11.747534078 -1.194847627 1 0 0 # ho 321 1 1 1.575000 2.474158711 -16.434354493 0.000000000 0 1 0 # ao 322 1 2 2.100000 3.292353111 -9.045742808 2.679766593 0 1 0 # st 323 1 2 2.100000 3.328683931 -15.064626680 2.686199476 0 1 0 # st 324 1 3 -1.050000 3.042855785 -17.936509520 1.061430252 0 1 0 # ob 325 1 3 -1.050000 3.482194769 -15.192125660 1.064187192 0 1 0 # ob 326 1 4 -0.950000 0.882455455 -16.223588464 0.993425143 0 1 0 # oh 327 1 3 -1.050000 -0.442812634 -14.508303559 3.298245183 0 1 0 # ob 328 1 3 -1.050000 3.029885813 -16.529108933 3.293650032 0 1 0 # ob 329 1 3 -1.050000 2.161264329 -14.023831544 3.055632561 0 1 0 # ob 330 1 5 0.425000 1.974005712 -16.230446978 1.194847627 0 1 0 # ho 331 1 1 1.575000 5.082326015 -11.951443182 0.000000000 0 1 0 # ao 332 1 2 2.100000 0.684185806 -13.528654119 2.679766593 0 1 0 # st 333 1 2 2.100000 0.776851388 -10.581715369 2.686199476 0 1 0 # st 334 1 3 -1.050000 0.491023242 -13.453598210 1.061430252 0 1 0 # ob 335 1 3 -1.050000 0.930362227 -10.709214349 1.064187192 0 1 0 # ob 336 1 4 -0.950000 3.490622759 -11.740677153 0.993425143 0 1 0 # oh 337 1 3 -1.050000 2.165354671 -10.025392248 3.298245183 0 1 0 # ob 338 1 3 -1.050000 0.478053271 -12.046197622 3.293650032 0 1 0 # ob 339 1 3 -1.050000 -0.390568214 -9.540920234 3.055632561 0 1 0 # ob 340 1 5 0.425000 4.582173017 -11.747535667 1.194847627 0 1 0 # ho 341 1 1 1.575000 2.516837596 -10.463116550 0.000000000 0 1 0 # ao 342 1 2 2.100000 1.698643196 -17.851728235 -2.679766593 0 1 0 # st 343 1 2 2.100000 1.662312376 -11.832844363 -2.686199476 0 1 0 # st 344 1 3 -1.050000 1.948140521 -8.960961522 -1.061430252 0 1 0 # ob 345 1 3 -1.050000 1.508801537 -11.705345382 -1.064187192 0 1 0 # ob 346 1 4 -0.950000 4.108540852 -10.673882579 -0.993425143 0 1 0 # oh 347 1 3 -1.050000 5.433808940 -12.389167484 -3.298245183 0 1 0 # ob 348 1 3 -1.050000 1.961110493 -10.368362109 -3.293650032 0 1 0 # ob 349 1 3 -1.050000 2.829731977 -12.873639498 -3.055632561 0 1 0 # ob 350 1 5 0.425000 3.016990594 -10.667024064 -1.194847627 0 1 0 # ho 351 1 1 1.575000 -0.091329709 -14.946027861 0.000000000 0 1 0 # ao 352 1 2 2.100000 4.306810500 -13.368816924 -2.679766593 0 1 0 # st 353 1 2 2.100000 4.214144919 -16.315755673 -2.686199476 0 1 0 # st 354 1 3 -1.050000 4.499973064 -13.443872833 -1.061430252 0 1 0 # ob 355 1 3 -1.050000 4.060634080 -16.188256693 -1.064187192 0 1 0 # ob 356 1 4 -0.950000 1.500373547 -15.156793890 -0.993425143 0 1 0 # oh 357 1 3 -1.050000 2.825641635 -16.872078794 -3.298245183 0 1 0 # ob 358 1 3 -1.050000 4.512943036 -14.851273420 -3.293650032 0 1 0 # ob 359 1 3 -1.050000 5.381564520 -17.356550809 -3.055632561 0 1 0 # ob 360 1 5 0.425000 0.408823289 -15.149935375 -1.194847627 0 1 0 # ho 361 1 1 1.575000 7.634158558 -16.434354493 0.000000000 0 1 0 # ao 362 1 2 2.100000 -12.187647042 -9.045742808 2.679766593 1 1 0 # st 363 1 2 2.100000 -12.151316222 -15.064626680 2.686199476 1 1 0 # st 364 1 3 -1.050000 8.202855633 -17.936509520 1.061430252 0 1 0 # ob 365 1 3 -1.050000 -11.997805383 -15.192125660 1.064187192 1 1 0 # ob 366 1 4 -0.950000 6.042455302 -16.223588464 0.993425143 0 1 0 # oh 367 1 3 -1.050000 4.717187214 -14.508303559 3.298245183 0 1 0 # ob 368 1 3 -1.050000 -12.450114339 -16.529108933 3.293650032 1 1 0 # ob 369 1 3 -1.050000 7.321264176 -14.023831544 3.055632561 0 1 0 # ob 370 1 5 0.425000 7.134005560 -16.230446978 1.194847627 0 1 0 # ho 371 1 1 1.575000 -10.397674137 -11.951443182 0.000000000 1 1 0 # ao 372 1 2 2.100000 5.844185654 -13.528654119 2.679766593 0 1 0 # st 373 1 2 2.100000 5.936851235 -10.581715369 2.686199476 0 1 0 # st 374 1 3 -1.050000 5.651023090 -13.453598210 1.061430252 0 1 0 # ob 375 1 3 -1.050000 6.090362074 -10.709214349 1.064187192 0 1 0 # ob 376 1 4 -0.950000 -11.989377393 -11.740677153 0.993425143 1 1 0 # oh 377 1 3 -1.050000 7.325354518 -10.025392248 3.298245183 0 1 0 # ob 378 1 3 -1.050000 5.638053118 -12.046197622 3.293650032 0 1 0 # ob 379 1 3 -1.050000 4.769431634 -9.540920234 3.055632561 0 1 0 # ob 380 1 5 0.425000 -10.897827136 -11.747535667 1.194847627 1 1 0 # ho 381 1 1 1.575000 7.676837443 -10.463116550 0.000000000 0 1 0 # ao 382 1 2 2.100000 6.858643043 -17.851728235 -2.679766593 0 1 0 # st 383 1 2 2.100000 6.822312223 -11.832844363 -2.686199476 0 1 0 # st 384 1 3 -1.050000 7.108140369 -8.960961522 -1.061430252 0 1 0 # ob 385 1 3 -1.050000 6.668801385 -11.705345382 -1.064187192 0 1 0 # ob 386 1 4 -0.950000 -11.371459301 -10.673882579 -0.993425143 1 1 0 # oh 387 1 3 -1.050000 -10.046191213 -12.389167484 -3.298245183 1 1 0 # ob 388 1 3 -1.050000 7.121110340 -10.368362109 -3.293650032 0 1 0 # ob 389 1 3 -1.050000 7.989731825 -12.873639498 -3.055632561 0 1 0 # ob 390 1 5 0.425000 8.176990442 -10.667024064 -1.194847627 0 1 0 # ho 391 1 1 1.575000 5.068670139 -14.946027861 0.000000000 0 1 0 # ao 392 1 2 2.100000 -11.173189652 -13.368816924 -2.679766593 1 1 0 # st 393 1 2 2.100000 -11.265855234 -16.315755673 -2.686199476 1 1 0 # st 394 1 3 -1.050000 -10.980027089 -13.443872833 -1.061430252 1 1 0 # ob 395 1 3 -1.050000 -11.419366073 -16.188256693 -1.064187192 1 1 0 # ob 396 1 4 -0.950000 6.660373395 -15.156793890 -0.993425143 0 1 0 # oh 397 1 3 -1.050000 7.985641483 -16.872078794 -3.298245183 0 1 0 # ob 398 1 3 -1.050000 -10.967057117 -14.851273420 -3.293650032 1 1 0 # ob 399 1 3 -1.050000 -10.098435632 -17.356550809 -3.055632561 1 1 0 # ob 400 1 5 0.425000 5.568823137 -15.149935375 -1.194847627 0 1 0 # ho 401 1 1 1.575000 -7.845841595 -16.434354493 0.000000000 1 1 0 # ao 402 1 2 2.100000 -7.027647194 -9.045742808 2.679766593 1 1 0 # st 403 1 2 2.100000 -6.991316374 -15.064626680 2.686199476 1 1 0 # st 404 1 3 -1.050000 -7.277144520 -17.936509520 1.061430252 1 1 0 # ob 405 1 3 -1.050000 -6.837805536 -15.192125660 1.064187192 1 1 0 # ob 406 1 4 -0.950000 -9.437544850 -16.223588464 0.993425143 1 1 0 # oh 407 1 3 -1.050000 -10.762812939 -14.508303559 3.298245183 1 1 0 # ob 408 1 3 -1.050000 -7.290114492 -16.529108933 3.293650032 1 1 0 # ob 409 1 3 -1.050000 -8.158735976 -14.023831544 3.055632561 1 1 0 # ob 410 1 5 0.425000 -8.345994593 -16.230446978 1.194847627 1 1 0 # ho 411 1 1 1.575000 -5.237674290 -11.951443182 0.000000000 1 1 0 # ao 412 1 2 2.100000 -9.635814499 -13.528654119 2.679766593 1 1 0 # st 413 1 2 2.100000 -9.543148917 -10.581715369 2.686199476 1 1 0 # st 414 1 3 -1.050000 -9.828977063 -13.453598210 1.061430252 1 1 0 # ob 415 1 3 -1.050000 -9.389638079 -10.709214349 1.064187192 1 1 0 # ob 416 1 4 -0.950000 -6.829377546 -11.740677153 0.993425143 1 1 0 # oh 417 1 3 -1.050000 -8.154645634 -10.025392248 3.298245183 1 1 0 # ob 418 1 3 -1.050000 -9.841947035 -12.046197622 3.293650032 1 1 0 # ob 419 1 3 -1.050000 -10.710568519 -9.540920234 3.055632561 1 1 0 # ob 420 1 5 0.425000 -5.737827288 -11.747535667 1.194847627 1 1 0 # ho 421 1 1 1.575000 -7.803162709 -10.463116550 0.000000000 1 1 0 # ao 422 1 2 2.100000 -8.621357110 -17.851728235 -2.679766593 1 1 0 # st 423 1 2 2.100000 -8.657687929 -11.832844363 -2.686199476 1 1 0 # st 424 1 3 -1.050000 -8.371859784 -8.960961522 -1.061430252 1 1 0 # ob 425 1 3 -1.050000 -8.811198768 -11.705345382 -1.064187192 1 1 0 # ob 426 1 4 -0.950000 -6.211459453 -10.673882579 -0.993425143 1 1 0 # oh 427 1 3 -1.050000 -4.886191365 -12.389167484 -3.298245183 1 1 0 # ob 428 1 3 -1.050000 -8.358889812 -10.368362109 -3.293650032 1 1 0 # ob 429 1 3 -1.050000 -7.490268328 -12.873639498 -3.055632561 1 1 0 # ob 430 1 5 0.425000 -7.303009711 -10.667024064 -1.194847627 1 1 0 # ho 431 1 1 1.575000 -10.411330014 -14.946027861 0.000000000 1 1 0 # ao 432 1 2 2.100000 -6.013189805 -13.368816924 -2.679766593 1 1 0 # st 433 1 2 2.100000 -6.105855387 -16.315755673 -2.686199476 1 1 0 # st 434 1 3 -1.050000 -5.820027241 -13.443872833 -1.061430252 1 1 0 # ob 435 1 3 -1.050000 -6.259366225 -16.188256693 -1.064187192 1 1 0 # ob 436 1 4 -0.950000 -8.819626758 -15.156793890 -0.993425143 1 1 0 # oh 437 1 3 -1.050000 -7.494358670 -16.872078794 -3.298245183 1 1 0 # ob 438 1 3 -1.050000 -5.807057269 -14.851273420 -3.293650032 1 1 0 # ob 439 1 3 -1.050000 -4.938435785 -17.356550809 -3.055632561 1 1 0 # ob 440 1 5 0.425000 -9.911177016 -15.149935375 -1.194847627 1 1 0 # ho 441 1 1 1.575000 -2.685841747 -16.434354493 0.000000000 1 1 0 # ao 442 1 2 2.100000 -1.867647347 -9.045742808 2.679766593 1 1 0 # st 443 1 2 2.100000 -1.831316527 -15.064626680 2.686199476 1 1 0 # st 444 1 3 -1.050000 -2.117144673 -17.936509520 1.061430252 1 1 0 # ob 445 1 3 -1.050000 -1.677805688 -15.192125660 1.064187192 1 1 0 # ob 446 1 4 -0.950000 -4.277545003 -16.223588464 0.993425143 1 1 0 # oh 447 1 3 -1.050000 -5.602813091 -14.508303559 3.298245183 1 1 0 # ob 448 1 3 -1.050000 -2.130114644 -16.529108933 3.293650032 1 1 0 # ob 449 1 3 -1.050000 -2.998736129 -14.023831544 3.055632561 1 1 0 # ob 450 1 5 0.425000 -3.185994745 -16.230446978 1.194847627 1 1 0 # ho 451 1 1 1.575000 -0.077674443 -11.951443182 0.000000000 1 1 0 # ao 452 1 2 2.100000 -4.475814651 -13.528654119 2.679766593 1 1 0 # st 453 1 2 2.100000 -4.383149070 -10.581715369 2.686199476 1 1 0 # st 454 1 3 -1.050000 -4.668977215 -13.453598210 1.061430252 1 1 0 # ob 455 1 3 -1.050000 -4.229638231 -10.709214349 1.064187192 1 1 0 # ob 456 1 4 -0.950000 -1.669377698 -11.740677153 0.993425143 1 1 0 # oh 457 1 3 -1.050000 -2.994645787 -10.025392248 3.298245183 1 1 0 # ob 458 1 3 -1.050000 -4.681947187 -12.046197622 3.293650032 1 1 0 # ob 459 1 3 -1.050000 -5.550568672 -9.540920234 3.055632561 1 1 0 # ob 460 1 5 0.425000 -0.577827441 -11.747535667 1.194847627 1 1 0 # ho 461 1 1 1.575000 -2.643162862 -10.463116550 0.000000000 1 1 0 # ao 462 1 2 2.100000 -3.461357262 -17.851728235 -2.679766593 1 1 0 # st 463 1 2 2.100000 -3.497688082 -11.832844363 -2.686199476 1 1 0 # st 464 1 3 -1.050000 -3.211859937 -8.960961522 -1.061430252 1 1 0 # ob 465 1 3 -1.050000 -3.651198921 -11.705345382 -1.064187192 1 1 0 # ob 466 1 4 -0.950000 -1.051459606 -10.673882579 -0.993425143 1 1 0 # oh 467 1 3 -1.050000 0.273808482 -12.389167484 -3.298245183 1 1 0 # ob 468 1 3 -1.050000 -3.198889965 -10.368362109 -3.293650032 1 1 0 # ob 469 1 3 -1.050000 -2.330268480 -12.873639498 -3.055632561 1 1 0 # ob 470 1 5 0.425000 -2.143009864 -10.667024064 -1.194847627 1 1 0 # ho 471 1 1 1.575000 -5.251330167 -14.946027861 0.000000000 1 1 0 # ao 472 1 2 2.100000 -0.853189958 -13.368816924 -2.679766593 1 1 0 # st 473 1 2 2.100000 -0.945855539 -16.315755673 -2.686199476 1 1 0 # st 474 1 3 -1.050000 -0.660027394 -13.443872833 -1.061430252 1 1 0 # ob 475 1 3 -1.050000 -1.099366378 -16.188256693 -1.064187192 1 1 0 # ob 476 1 4 -0.950000 -3.659626911 -15.156793890 -0.993425143 1 1 0 # oh 477 1 3 -1.050000 -2.334358822 -16.872078794 -3.298245183 1 1 0 # ob 478 1 3 -1.050000 -0.647057422 -14.851273420 -3.293650032 1 1 0 # ob 479 1 3 -1.050000 0.221564062 -17.356550809 -3.055632561 1 1 0 # ob 480 1 5 0.425000 -4.751177168 -15.149935375 -1.194847627 1 1 0 # ho 481 1 1 1.575000 2.530493472 -7.468531871 0.000000000 0 1 0 # ao 482 1 2 2.100000 3.348687873 -0.079920186 2.679766593 0 1 0 # st 483 1 2 2.100000 3.385018693 -6.098804058 2.686199476 0 1 0 # st 484 1 3 -1.050000 3.099190547 -8.970686899 1.061430252 0 1 0 # ob 485 1 3 -1.050000 3.538529531 -6.226303039 1.064187192 0 1 0 # ob 486 1 4 -0.950000 0.938790217 -7.257765842 0.993425143 0 1 0 # oh 487 1 3 -1.050000 -0.386477872 -5.542480937 3.298245183 0 1 0 # ob 488 1 3 -1.050000 3.086220575 -7.563286311 3.293650032 0 1 0 # ob 489 1 3 -1.050000 2.217599091 -5.058008923 3.055632561 0 1 0 # ob 490 1 5 0.425000 2.030340474 -7.264624356 1.194847627 0 1 0 # ho 491 1 1 1.575000 5.138660777 -2.985620560 0.000000000 0 1 0 # ao 492 1 2 2.100000 0.740520568 -4.562831497 2.679766593 0 1 0 # st 493 1 2 2.100000 0.833186150 -1.615892747 2.686199476 0 1 0 # st 494 1 3 -1.050000 0.547358004 -4.487775588 1.061430252 0 1 0 # ob 495 1 3 -1.050000 0.986696988 -1.743391728 1.064187192 0 1 0 # ob 496 1 4 -0.950000 3.546957521 -2.774854531 0.993425143 0 1 0 # oh 497 1 3 -1.050000 2.221689433 -1.059569627 3.298245183 0 1 0 # ob 498 1 3 -1.050000 0.534388032 -3.080375001 3.293650032 0 1 0 # ob 499 1 3 -1.050000 -0.334233452 -0.575097612 3.055632561 0 1 0 # ob 500 1 5 0.425000 4.638507779 -2.781713046 1.194847627 0 1 0 # ho 501 1 1 1.575000 2.573172358 -1.497293928 0.000000000 0 1 0 # ao 502 1 2 2.100000 1.754977957 -8.885905613 -2.679766593 0 1 0 # st 503 1 2 2.100000 1.718647138 -2.867021741 -2.686199476 0 1 0 # st 504 1 3 -1.050000 2.004475283 0.004861099 -1.061430252 0 1 0 # ob 505 1 3 -1.050000 1.565136299 -2.739522761 -1.064187192 0 1 0 # ob 506 1 4 -0.950000 4.164875614 -1.708059957 -0.993425143 0 1 0 # oh 507 1 3 -1.050000 5.490143702 -3.423344862 -3.298245183 0 1 0 # ob 508 1 3 -1.050000 2.017445255 -1.402539488 -3.293650032 0 1 0 # ob 509 1 3 -1.050000 2.886066739 -3.907816877 -3.055632561 0 1 0 # ob 510 1 5 0.425000 3.073325356 -1.701201443 -1.194847627 0 1 0 # ho 511 1 1 1.575000 -0.034994947 -5.980205239 0.000000000 0 1 0 # ao 512 1 2 2.100000 4.363145262 -4.402994302 -2.679766593 0 1 0 # st 513 1 2 2.100000 4.270479680 -7.349933052 -2.686199476 0 1 0 # st 514 1 3 -1.050000 4.556307826 -4.478050211 -1.061430252 0 1 0 # ob 515 1 3 -1.050000 4.116968842 -7.222434071 -1.064187192 0 1 0 # ob 516 1 4 -0.950000 1.556708309 -6.190971268 -0.993425143 0 1 0 # oh 517 1 3 -1.050000 2.881976397 -7.906256173 -3.298245183 0 1 0 # ob 518 1 3 -1.050000 4.569277798 -5.885450799 -3.293650032 0 1 0 # ob 519 1 3 -1.050000 5.437899282 -8.390728187 -3.055632561 0 1 0 # ob 520 1 5 0.425000 0.465158051 -6.184112754 -1.194847627 0 1 0 # ho 521 1 1 1.575000 7.690493320 -7.468531871 0.000000000 0 1 0 # ao 522 1 2 2.100000 -12.131312280 -0.079920186 2.679766593 1 1 0 # st 523 1 2 2.100000 -12.094981460 -6.098804058 2.686199476 1 1 0 # st 524 1 3 -1.050000 8.259190394 -8.970686899 1.061430252 0 1 0 # ob 525 1 3 -1.050000 -11.941470621 -6.226303039 1.064187192 1 1 0 # ob 526 1 4 -0.950000 6.098790064 -7.257765842 0.993425143 0 1 0 # oh 527 1 3 -1.050000 4.773521976 -5.542480937 3.298245183 0 1 0 # ob 528 1 3 -1.050000 -12.393779577 -7.563286311 3.293650032 1 1 0 # ob 529 1 3 -1.050000 7.377598938 -5.058008923 3.055632561 0 1 0 # ob 530 1 5 0.425000 7.190340322 -7.264624356 1.194847627 0 1 0 # ho 531 1 1 1.575000 -10.341339376 -2.985620560 0.000000000 1 1 0 # ao 532 1 2 2.100000 5.900520415 -4.562831497 2.679766593 0 1 0 # st 533 1 2 2.100000 5.993185997 -1.615892747 2.686199476 0 1 0 # st 534 1 3 -1.050000 5.707357852 -4.487775588 1.061430252 0 1 0 # ob 535 1 3 -1.050000 6.146696836 -1.743391728 1.064187192 0 1 0 # ob 536 1 4 -0.950000 -11.933042631 -2.774854531 0.993425143 1 1 0 # oh 537 1 3 -1.050000 7.381689280 -1.059569627 3.298245183 0 1 0 # ob 538 1 3 -1.050000 5.694387880 -3.080375001 3.293650032 0 1 0 # ob 539 1 3 -1.050000 4.825766395 -0.575097612 3.055632561 0 1 0 # ob 540 1 5 0.425000 -10.841492374 -2.781713046 1.194847627 1 1 0 # ho 541 1 1 1.575000 7.733172205 -1.497293928 0.000000000 0 1 0 # ao 542 1 2 2.100000 6.914977805 -8.885905613 -2.679766593 0 1 0 # st 543 1 2 2.100000 6.878646985 -2.867021741 -2.686199476 0 1 0 # st 544 1 3 -1.050000 7.164475130 0.004861099 -1.061430252 0 1 0 # ob 545 1 3 -1.050000 6.725136146 -2.739522761 -1.064187192 0 1 0 # ob 546 1 4 -0.950000 -11.315124539 -1.708059957 -0.993425143 1 1 0 # oh 547 1 3 -1.050000 -9.989856451 -3.423344862 -3.298245183 1 1 0 # ob 548 1 3 -1.050000 7.177445102 -1.402539488 -3.293650032 0 1 0 # ob 549 1 3 -1.050000 8.046066587 -3.907816877 -3.055632561 0 1 0 # ob 550 1 5 0.425000 8.233325203 -1.701201443 -1.194847627 0 1 0 # ho 551 1 1 1.575000 5.125004900 -5.980205239 0.000000000 0 1 0 # ao 552 1 2 2.100000 -11.116854891 -4.402994302 -2.679766593 1 1 0 # st 553 1 2 2.100000 -11.209520472 -7.349933052 -2.686199476 1 1 0 # st 554 1 3 -1.050000 -10.923692327 -4.478050211 -1.061430252 1 1 0 # ob 555 1 3 -1.050000 -11.363031311 -7.222434071 -1.064187192 1 1 0 # ob 556 1 4 -0.950000 6.716708156 -6.190971268 -0.993425143 0 1 0 # oh 557 1 3 -1.050000 8.041976245 -7.906256173 -3.298245183 0 1 0 # ob 558 1 3 -1.050000 -10.910722355 -5.885450799 -3.293650032 1 1 0 # ob 559 1 3 -1.050000 -10.042100871 -8.390728187 -3.055632561 1 1 0 # ob 560 1 5 0.425000 5.625157899 -6.184112754 -1.194847627 0 1 0 # ho 561 1 1 1.575000 -7.789506833 -7.468531871 0.000000000 1 1 0 # ao 562 1 2 2.100000 -6.971312432 -0.079920186 2.679766593 1 1 0 # st 563 1 2 2.100000 -6.934981613 -6.098804058 2.686199476 1 1 0 # st 564 1 3 -1.050000 -7.220809758 -8.970686899 1.061430252 1 1 0 # ob 565 1 3 -1.050000 -6.781470774 -6.226303039 1.064187192 1 1 0 # ob 566 1 4 -0.950000 -9.381210089 -7.257765842 0.993425143 1 1 0 # oh 567 1 3 -1.050000 -10.706478177 -5.542480937 3.298245183 1 1 0 # ob 568 1 3 -1.050000 -7.233779730 -7.563286311 3.293650032 1 1 0 # ob 569 1 3 -1.050000 -8.102401214 -5.058008923 3.055632561 1 1 0 # ob 570 1 5 0.425000 -8.289659831 -7.264624356 1.194847627 1 1 0 # ho 571 1 1 1.575000 -5.181339528 -2.985620560 0.000000000 1 1 0 # ao 572 1 2 2.100000 -9.579479737 -4.562831497 2.679766593 1 1 0 # st 573 1 2 2.100000 -9.486814155 -1.615892747 2.686199476 1 1 0 # st 574 1 3 -1.050000 -9.772642301 -4.487775588 1.061430252 1 1 0 # ob 575 1 3 -1.050000 -9.333303317 -1.743391728 1.064187192 1 1 0 # ob 576 1 4 -0.950000 -6.773042784 -2.774854531 0.993425143 1 1 0 # oh 577 1 3 -1.050000 -8.098310872 -1.059569627 3.298245183 1 1 0 # ob 578 1 3 -1.050000 -9.785612273 -3.080375001 3.293650032 1 1 0 # ob 579 1 3 -1.050000 -10.654233757 -0.575097612 3.055632561 1 1 0 # ob 580 1 5 0.425000 -5.681492526 -2.781713046 1.194847627 1 1 0 # ho 581 1 1 1.575000 -7.746827947 -1.497293928 0.000000000 1 1 0 # ao 582 1 2 2.100000 -8.565022348 -8.885905613 -2.679766593 1 1 0 # st 583 1 2 2.100000 -8.601353168 -2.867021741 -2.686199476 1 1 0 # st 584 1 3 -1.050000 -8.315525022 0.004861099 -1.061430252 1 1 0 # ob 585 1 3 -1.050000 -8.754864006 -2.739522761 -1.064187192 1 1 0 # ob 586 1 4 -0.950000 -6.155124692 -1.708059957 -0.993425143 1 1 0 # oh 587 1 3 -1.050000 -4.829856603 -3.423344862 -3.298245183 1 1 0 # ob 588 1 3 -1.050000 -8.302555050 -1.402539488 -3.293650032 1 1 0 # ob 589 1 3 -1.050000 -7.433933566 -3.907816877 -3.055632561 1 1 0 # ob 590 1 5 0.425000 -7.246674949 -1.701201443 -1.194847627 1 1 0 # ho 591 1 1 1.575000 -10.354995252 -5.980205239 0.000000000 1 1 0 # ao 592 1 2 2.100000 -5.956855043 -4.402994302 -2.679766593 1 1 0 # st 593 1 2 2.100000 -6.049520625 -7.349933052 -2.686199476 1 1 0 # st 594 1 3 -1.050000 -5.763692479 -4.478050211 -1.061430252 1 1 0 # ob 595 1 3 -1.050000 -6.203031463 -7.222434071 -1.064187192 1 1 0 # ob 596 1 4 -0.950000 -8.763291996 -6.190971268 -0.993425143 1 1 0 # oh 597 1 3 -1.050000 -7.438023908 -7.906256173 -3.298245183 1 1 0 # ob 598 1 3 -1.050000 -5.750722507 -5.885450799 -3.293650032 1 1 0 # ob 599 1 3 -1.050000 -4.882101023 -8.390728187 -3.055632561 1 1 0 # ob 600 1 5 0.425000 -9.854842254 -6.184112754 -1.194847627 1 1 0 # ho 601 1 1 1.575000 -2.629506985 -7.468531871 0.000000000 1 1 0 # ao 602 1 2 2.100000 -1.811312585 -0.079920186 2.679766593 1 1 0 # st 603 1 2 2.100000 -1.774981765 -6.098804058 2.686199476 1 1 0 # st 604 1 3 -1.050000 -2.060809911 -8.970686899 1.061430252 1 1 0 # ob 605 1 3 -1.050000 -1.621470927 -6.226303039 1.064187192 1 1 0 # ob 606 1 4 -0.950000 -4.221210241 -7.257765842 0.993425143 1 1 0 # oh 607 1 3 -1.050000 -5.546478330 -5.542480937 3.298245183 1 1 0 # ob 608 1 3 -1.050000 -2.073779883 -7.563286311 3.293650032 1 1 0 # ob 609 1 3 -1.050000 -2.942401367 -5.058008923 3.055632561 1 1 0 # ob 610 1 5 0.425000 -3.129659984 -7.264624356 1.194847627 1 1 0 # ho 611 1 1 1.575000 -0.021339681 -2.985620560 0.000000000 1 1 0 # ao 612 1 2 2.100000 -4.419479890 -4.562831497 2.679766593 1 1 0 # st 613 1 2 2.100000 -4.326814308 -1.615892747 2.686199476 1 1 0 # st 614 1 3 -1.050000 -4.612642454 -4.487775588 1.061430252 1 1 0 # ob 615 1 3 -1.050000 -4.173303469 -1.743391728 1.064187192 1 1 0 # ob 616 1 4 -0.950000 -1.613042937 -2.774854531 0.993425143 1 1 0 # oh 617 1 3 -1.050000 -2.938311025 -1.059569627 3.298245183 1 1 0 # ob 618 1 3 -1.050000 -4.625612425 -3.080375001 3.293650032 1 1 0 # ob 619 1 3 -1.050000 -5.494233910 -0.575097612 3.055632561 1 1 0 # ob 620 1 5 0.425000 -0.521492679 -2.781713046 1.194847627 1 1 0 # ho 621 1 1 1.575000 -2.586828100 -1.497293928 0.000000000 1 1 0 # ao 622 1 2 2.100000 -3.405022500 -8.885905613 -2.679766593 1 1 0 # st 623 1 2 2.100000 -3.441353320 -2.867021741 -2.686199476 1 1 0 # st 624 1 3 -1.050000 -3.155525175 0.004861099 -1.061430252 1 1 0 # ob 625 1 3 -1.050000 -3.594864159 -2.739522761 -1.064187192 1 1 0 # ob 626 1 4 -0.950000 -0.995124844 -1.708059957 -0.993425143 1 1 0 # oh 627 1 3 -1.050000 0.330143244 -3.423344862 -3.298245183 1 1 0 # ob 628 1 3 -1.050000 -3.142555203 -1.402539488 -3.293650032 1 1 0 # ob 629 1 3 -1.050000 -2.273933719 -3.907816877 -3.055632561 1 1 0 # ob 630 1 5 0.425000 -2.086675102 -1.701201443 -1.194847627 1 1 0 # ho 631 1 1 1.575000 -5.194995405 -5.980205239 0.000000000 1 1 0 # ao 632 1 2 2.100000 -0.796855196 -4.402994302 -2.679766593 1 1 0 # st 633 1 2 2.100000 -0.889520777 -7.349933052 -2.686199476 1 1 0 # st 634 1 3 -1.050000 -0.603692632 -4.478050211 -1.061430252 1 1 0 # ob 635 1 3 -1.050000 -1.043031616 -7.222434071 -1.064187192 1 1 0 # ob 636 1 4 -0.950000 -3.603292149 -6.190971268 -0.993425143 1 1 0 # oh 637 1 3 -1.050000 -2.278024061 -7.906256173 -3.298245183 1 1 0 # ob 638 1 3 -1.050000 -0.590722660 -5.885450799 -3.293650032 1 1 0 # ob 639 1 3 -1.050000 0.277898824 -8.390728187 -3.055632561 1 1 0 # ob 640 1 5 0.425000 -4.694842406 -6.184112754 -1.194847627 1 1 0 # ho 641 1 1 1.575000 0.889889112 1.315464043 9.189872068 0 0 0 # ao 642 1 2 2.100000 5.101961261 9.067732250 -6.523590700 0 0 1 # st 643 1 2 2.100000 5.138292081 3.048848378 -6.517157818 0 0 1 # st 644 1 3 -1.050000 4.852463935 0.176965538 -8.141927041 0 0 1 # ob 645 1 3 -1.050000 5.291802919 2.921349398 -8.139170101 0 0 1 # ob 646 1 4 -0.950000 2.692063605 1.889886595 -8.209932150 0 0 1 # oh 647 1 3 -1.050000 1.366795516 3.605171499 -5.905112111 0 0 1 # ob 648 1 3 -1.050000 4.839493963 1.584366125 -5.909707262 0 0 1 # ob 649 1 3 -1.050000 3.970872479 4.089643514 -6.147724732 0 0 1 # ob 650 1 5 0.425000 3.783613862 1.883028080 -8.008509666 0 0 1 # ho 651 1 1 1.575000 3.498056417 5.798375353 9.189872068 0 0 0 # ao 652 1 2 2.100000 2.493793956 4.584820940 -6.523590700 0 0 1 # st 653 1 2 2.100000 2.586459538 7.531759689 -6.517157818 0 0 1 # st 654 1 3 -1.050000 2.300631392 4.659876849 -8.141927041 0 0 1 # ob 655 1 3 -1.050000 2.739970376 7.404260709 -8.139170101 0 0 1 # ob 656 1 4 -0.950000 5.300230909 6.372797905 -8.209932150 0 0 1 # oh 657 1 3 -1.050000 3.974962821 8.088082810 -5.905112111 0 0 1 # ob 658 1 3 -1.050000 2.287661420 6.067277436 -5.909707262 0 0 1 # ob 659 1 3 -1.050000 1.419039936 8.572554825 -6.147724732 0 0 1 # ob 660 1 5 0.425000 6.391781167 6.365939391 -8.008509666 0 0 1 # ho 661 1 1 1.575000 0.932567998 7.286701985 9.189872068 0 0 0 # ao 662 1 2 2.100000 0.114373597 -0.101909699 6.510105475 0 0 0 # st 663 1 2 2.100000 0.078042778 5.916974173 6.503672592 0 0 0 # st 664 1 3 -1.050000 0.363870923 8.788857013 8.128441816 0 0 0 # ob 665 1 3 -1.050000 -0.075468061 6.044473153 8.125684876 0 0 0 # ob 666 1 4 -0.950000 2.524271254 7.075935956 8.196446925 0 0 0 # oh 667 1 3 -1.050000 3.849539342 5.360651052 5.891626886 0 0 0 # ob 668 1 3 -1.050000 0.376840895 7.381456426 5.896222036 0 0 0 # ob 669 1 3 -1.050000 1.245462379 4.876179037 6.134239507 0 0 0 # ob 670 1 5 0.425000 1.432720996 7.082794471 7.995024441 0 0 0 # ho 671 1 1 1.575000 -1.675599307 2.803790675 9.189872068 0 0 0 # ao 672 1 2 2.100000 2.722540902 4.381001611 6.510105475 0 0 0 # st 673 1 2 2.100000 2.629875320 1.434062862 6.503672592 0 0 0 # st 674 1 3 -1.050000 2.915703466 4.305945702 8.128441816 0 0 0 # ob 675 1 3 -1.050000 2.476364482 1.561561842 8.125684876 0 0 0 # ob 676 1 4 -0.950000 -0.083896051 2.593024646 8.196446925 0 0 0 # oh 677 1 3 -1.050000 1.241372037 0.877739741 5.891626886 0 0 0 # ob 678 1 3 -1.050000 2.928673438 2.898545115 5.896222036 0 0 0 # ob 679 1 3 -1.050000 3.797294922 0.393267726 6.134239507 0 0 0 # ob 680 1 5 0.425000 -1.175446309 2.599883160 7.995024441 0 0 0 # ho 681 1 1 1.575000 6.049888960 1.315464043 9.189872068 0 0 0 # ao 682 1 2 2.100000 -10.378038892 9.067732250 -6.523590700 1 0 1 # st 683 1 2 2.100000 -10.341708072 3.048848378 -6.517157818 1 0 1 # st 684 1 3 -1.050000 10.012463782 0.176965538 -8.141927041 0 0 1 # ob 685 1 3 -1.050000 -10.188197233 2.921349398 -8.139170101 1 0 1 # ob 686 1 4 -0.950000 7.852063452 1.889886595 -8.209932150 0 0 1 # oh 687 1 3 -1.050000 6.526795364 3.605171499 -5.905112111 0 0 1 # ob 688 1 3 -1.050000 -10.640506189 1.584366125 -5.909707262 1 0 1 # ob 689 1 3 -1.050000 9.130872326 4.089643514 -6.147724732 0 0 1 # ob 690 1 5 0.425000 8.943613710 1.883028080 -8.008509666 0 0 1 # ho 691 1 1 1.575000 -11.981943736 5.798375353 9.189872068 1 0 0 # ao 692 1 2 2.100000 7.653793804 4.584820940 -6.523590700 0 0 1 # st 693 1 2 2.100000 7.746459385 7.531759689 -6.517157818 0 0 1 # st 694 1 3 -1.050000 7.460631240 4.659876849 -8.141927041 0 0 1 # ob 695 1 3 -1.050000 7.899970224 7.404260709 -8.139170101 0 0 1 # ob 696 1 4 -0.950000 -10.179769243 6.372797905 -8.209932150 1 0 1 # oh 697 1 3 -1.050000 9.134962668 8.088082810 -5.905112111 0 0 1 # ob 698 1 3 -1.050000 7.447661268 6.067277436 -5.909707262 0 0 1 # ob 699 1 3 -1.050000 6.579039784 8.572554825 -6.147724732 0 0 1 # ob 700 1 5 0.425000 -9.088218986 6.365939391 -8.008509666 1 0 1 # ho 701 1 1 1.575000 6.092567845 7.286701985 9.189872068 0 0 0 # ao 702 1 2 2.100000 5.274373445 -0.101909699 6.510105475 0 0 0 # st 703 1 2 2.100000 5.238042625 5.916974173 6.503672592 0 0 0 # st 704 1 3 -1.050000 5.523870771 8.788857013 8.128441816 0 0 0 # ob 705 1 3 -1.050000 5.084531786 6.044473153 8.125684876 0 0 0 # ob 706 1 4 -0.950000 -12.955728899 7.075935956 8.196446925 1 0 0 # oh 707 1 3 -1.050000 -11.630460811 5.360651052 5.891626886 1 0 0 # ob 708 1 3 -1.050000 5.536840742 7.381456426 5.896222036 0 0 0 # ob 709 1 3 -1.050000 6.405462227 4.876179037 6.134239507 0 0 0 # ob 710 1 5 0.425000 6.592720843 7.082794471 7.995024441 0 0 0 # ho 711 1 1 1.575000 3.484400541 2.803790675 9.189872068 0 0 0 # ao 712 1 2 2.100000 -12.757459251 4.381001611 6.510105475 1 0 0 # st 713 1 2 2.100000 -12.850124832 1.434062862 6.503672592 1 0 0 # st 714 1 3 -1.050000 -12.564296687 4.305945702 8.128441816 1 0 0 # ob 715 1 3 -1.050000 -13.003635671 1.561561842 8.125684876 1 0 0 # ob 716 1 4 -0.950000 5.076103796 2.593024646 8.196446925 0 0 0 # oh 717 1 3 -1.050000 6.401371885 0.877739741 5.891626886 0 0 0 # ob 718 1 3 -1.050000 -12.551326715 2.898545115 5.896222036 1 0 0 # ob 719 1 3 -1.050000 -11.682705231 0.393267726 6.134239507 1 0 0 # ob 720 1 5 0.425000 3.984553539 2.599883160 7.995024441 0 0 0 # ho 721 1 1 1.575000 -9.430111193 1.315464043 9.189872068 1 0 0 # ao 722 1 2 2.100000 -5.218039044 9.067732250 -6.523590700 1 0 1 # st 723 1 2 2.100000 -5.181708225 3.048848378 -6.517157818 1 0 1 # st 724 1 3 -1.050000 -5.467536370 0.176965538 -8.141927041 1 0 1 # ob 725 1 3 -1.050000 -5.028197386 2.921349398 -8.139170101 1 0 1 # ob 726 1 4 -0.950000 -7.627936701 1.889886595 -8.209932150 1 0 1 # oh 727 1 3 -1.050000 -8.953204789 3.605171499 -5.905112111 1 0 1 # ob 728 1 3 -1.050000 -5.480506342 1.584366125 -5.909707262 1 0 1 # ob 729 1 3 -1.050000 -6.349127826 4.089643514 -6.147724732 1 0 1 # ob 730 1 5 0.425000 -6.536386443 1.883028080 -8.008509666 1 0 1 # ho 731 1 1 1.575000 -6.821943888 5.798375353 9.189872068 1 0 0 # ao 732 1 2 2.100000 -7.826206349 4.584820940 -6.523590700 1 0 1 # st 733 1 2 2.100000 -7.733540767 7.531759689 -6.517157818 1 0 1 # st 734 1 3 -1.050000 -8.019368913 4.659876849 -8.141927041 1 0 1 # ob 735 1 3 -1.050000 -7.580029929 7.404260709 -8.139170101 1 0 1 # ob 736 1 4 -0.950000 -5.019769396 6.372797905 -8.209932150 1 0 1 # oh 737 1 3 -1.050000 -6.345037484 8.088082810 -5.905112111 1 0 1 # ob 738 1 3 -1.050000 -8.032338885 6.067277436 -5.909707262 1 0 1 # ob 739 1 3 -1.050000 -8.900960369 8.572554825 -6.147724732 1 0 1 # ob 740 1 5 0.425000 -3.928219138 6.365939391 -8.008509666 1 0 1 # ho 741 1 1 1.575000 -9.387432307 7.286701985 9.189872068 1 0 0 # ao 742 1 2 2.100000 -10.205626708 -0.101909699 6.510105475 1 0 0 # st 743 1 2 2.100000 -10.241957528 5.916974173 6.503672592 1 0 0 # st 744 1 3 -1.050000 -9.956129382 8.788857013 8.128441816 1 0 0 # ob 745 1 3 -1.050000 -10.395468366 6.044473153 8.125684876 1 0 0 # ob 746 1 4 -0.950000 -7.795729052 7.075935956 8.196446925 1 0 0 # oh 747 1 3 -1.050000 -6.470460963 5.360651052 5.891626886 1 0 0 # ob 748 1 3 -1.050000 -9.943159410 7.381456426 5.896222036 1 0 0 # ob 749 1 3 -1.050000 -9.074537926 4.876179037 6.134239507 1 0 0 # ob 750 1 5 0.425000 -8.887279309 7.082794471 7.995024441 1 0 0 # ho 751 1 1 1.575000 -11.995599612 2.803790675 9.189872068 1 0 0 # ao 752 1 2 2.100000 -7.597459403 4.381001611 6.510105475 1 0 0 # st 753 1 2 2.100000 -7.690124985 1.434062862 6.503672592 1 0 0 # st 754 1 3 -1.050000 -7.404296839 4.305945702 8.128441816 1 0 0 # ob 755 1 3 -1.050000 -7.843635823 1.561561842 8.125684876 1 0 0 # ob 756 1 4 -0.950000 -10.403896356 2.593024646 8.196446925 1 0 0 # oh 757 1 3 -1.050000 -9.078628268 0.877739741 5.891626886 1 0 0 # ob 758 1 3 -1.050000 -7.391326867 2.898545115 5.896222036 1 0 0 # ob 759 1 3 -1.050000 -6.522705383 0.393267726 6.134239507 1 0 0 # ob 760 1 5 0.425000 -11.495446614 2.599883160 7.995024441 1 0 0 # ho 761 1 1 1.575000 -4.270111345 1.315464043 9.189872068 1 0 0 # ao 762 1 2 2.100000 -0.058039197 9.067732250 -6.523590700 1 0 1 # st 763 1 2 2.100000 -0.021708377 3.048848378 -6.517157818 1 0 1 # st 764 1 3 -1.050000 -0.307536523 0.176965538 -8.141927041 1 0 1 # ob 765 1 3 -1.050000 0.131802461 2.921349398 -8.139170101 1 0 1 # ob 766 1 4 -0.950000 -2.467936853 1.889886595 -8.209932150 1 0 1 # oh 767 1 3 -1.050000 -3.793204941 3.605171499 -5.905112111 1 0 1 # ob 768 1 3 -1.050000 -0.320506495 1.584366125 -5.909707262 1 0 1 # ob 769 1 3 -1.050000 -1.189127979 4.089643514 -6.147724732 1 0 1 # ob 770 1 5 0.425000 -1.376386596 1.883028080 -8.008509666 1 0 1 # ho 771 1 1 1.575000 -1.661944041 5.798375353 9.189872068 1 0 0 # ao 772 1 2 2.100000 -2.666206502 4.584820940 -6.523590700 1 0 1 # st 773 1 2 2.100000 -2.573540920 7.531759689 -6.517157818 1 0 1 # st 774 1 3 -1.050000 -2.859369065 4.659876849 -8.141927041 1 0 1 # ob 775 1 3 -1.050000 -2.420030081 7.404260709 -8.139170101 1 0 1 # ob 776 1 4 -0.950000 0.140230451 6.372797905 -8.209932150 1 0 1 # oh 777 1 3 -1.050000 -1.185037637 8.088082810 -5.905112111 1 0 1 # ob 778 1 3 -1.050000 -2.872339037 6.067277436 -5.909707262 1 0 1 # ob 779 1 3 -1.050000 -3.740960522 8.572554825 -6.147724732 1 0 1 # ob 780 1 5 0.425000 1.231780709 6.365939391 -8.008509666 1 0 1 # ho 781 1 1 1.575000 -4.227432460 7.286701985 9.189872068 1 0 0 # ao 782 1 2 2.100000 -5.045626860 -0.101909699 6.510105475 1 0 0 # st 783 1 2 2.100000 -5.081957680 5.916974173 6.503672592 1 0 0 # st 784 1 3 -1.050000 -4.796129535 8.788857013 8.128441816 1 0 0 # ob 785 1 3 -1.050000 -5.235468519 6.044473153 8.125684876 1 0 0 # ob 786 1 4 -0.950000 -2.635729204 7.075935956 8.196446925 1 0 0 # oh 787 1 3 -1.050000 -1.310461116 5.360651052 5.891626886 1 0 0 # ob 788 1 3 -1.050000 -4.783159563 7.381456426 5.896222036 1 0 0 # ob 789 1 3 -1.050000 -3.914538079 4.876179037 6.134239507 1 0 0 # ob 790 1 5 0.425000 -3.727279462 7.082794471 7.995024441 1 0 0 # ho 791 1 1 1.575000 -6.835599765 2.803790675 9.189872068 1 0 0 # ao 792 1 2 2.100000 -2.437459556 4.381001611 6.510105475 1 0 0 # st 793 1 2 2.100000 -2.530125137 1.434062862 6.503672592 1 0 0 # st 794 1 3 -1.050000 -2.244296992 4.305945702 8.128441816 1 0 0 # ob 795 1 3 -1.050000 -2.683635976 1.561561842 8.125684876 1 0 0 # ob 796 1 4 -0.950000 -5.243896509 2.593024646 8.196446925 1 0 0 # oh 797 1 3 -1.050000 -3.918628421 0.877739741 5.891626886 1 0 0 # ob 798 1 3 -1.050000 -2.231327020 2.898545115 5.896222036 1 0 0 # ob 799 1 3 -1.050000 -1.362705536 0.393267726 6.134239507 1 0 0 # ob 800 1 5 0.425000 -6.335446766 2.599883160 7.995024441 1 0 0 # ho 801 1 1 1.575000 0.946223874 10.281286664 9.189872068 0 0 0 # ao 802 1 2 2.100000 4.932957348 -17.829737203 -6.523590700 0 1 1 # st 803 1 2 2.100000 5.194626842 12.014671000 -6.517157818 0 0 1 # st 804 1 3 -1.050000 4.908798697 9.142788159 -8.141927041 0 0 1 # ob 805 1 3 -1.050000 5.348137681 11.887172019 -8.139170101 0 0 1 # ob 806 1 4 -0.950000 2.748398366 10.855709216 -8.209932150 0 0 1 # oh 807 1 3 -1.050000 1.423130278 12.570994121 -5.905112111 0 0 1 # ob 808 1 3 -1.050000 4.895828725 10.550188747 -5.909707262 0 0 1 # ob 809 1 3 -1.050000 4.027207241 13.055466135 -6.147724732 0 0 1 # ob 810 1 5 0.425000 3.839948624 10.848850702 -8.008509666 0 0 1 # ho 811 1 1 1.575000 3.554391179 14.764197975 9.189872068 0 0 0 # ao 812 1 2 2.100000 2.550128718 13.550643561 -6.523590700 0 0 1 # st 813 1 2 2.100000 2.642794300 16.497582311 -6.517157818 0 0 1 # st 814 1 3 -1.050000 2.356966154 13.625699470 -8.141927041 0 0 1 # ob 815 1 3 -1.050000 2.796305138 16.370083330 -8.139170101 0 0 1 # ob 816 1 4 -0.950000 5.356565671 15.338620527 -8.209932150 0 0 1 # oh 817 1 3 -1.050000 4.031297583 17.053905432 -5.905112111 0 0 1 # ob 818 1 3 -1.050000 2.343996182 15.033100058 -5.909707262 0 0 1 # ob 819 1 3 -1.050000 1.475374698 17.538377446 -6.147724732 0 0 1 # ob 820 1 5 0.425000 6.448115929 15.331762013 -8.008509666 0 0 1 # ho 821 1 1 1.575000 0.988902760 16.252524607 9.189872068 0 0 0 # ao 822 1 2 2.100000 0.170708359 8.863912922 6.510105475 0 0 0 # st 823 1 2 2.100000 0.134377539 14.882796794 6.503672592 0 0 0 # st 824 1 3 -1.050000 0.194867010 -18.108612440 8.128441816 0 1 0 # ob 825 1 3 -1.050000 -0.019133299 15.010295775 8.125684876 0 0 0 # ob 826 1 4 -0.950000 2.580606015 16.041758578 8.196446925 0 0 0 # oh 827 1 3 -1.050000 3.905874104 14.326473673 5.891626886 0 0 0 # ob 828 1 3 -1.050000 0.433175657 16.347279047 5.896222036 0 0 0 # ob 829 1 3 -1.050000 1.301797141 13.842001659 6.134239507 0 0 0 # ob 830 1 5 0.425000 1.489055758 16.048617092 7.995024441 0 0 0 # ho 831 1 1 1.575000 -1.619264545 11.769613296 9.189872068 0 0 0 # ao 832 1 2 2.100000 2.778875664 13.346824233 6.510105475 0 0 0 # st 833 1 2 2.100000 2.686210082 10.399885483 6.503672592 0 0 0 # st 834 1 3 -1.050000 2.972038228 13.271768324 8.128441816 0 0 0 # ob 835 1 3 -1.050000 2.532699244 10.527384464 8.125684876 0 0 0 # ob 836 1 4 -0.950000 -0.027561289 11.558847267 8.196446925 0 0 0 # oh 837 1 3 -1.050000 1.297706799 9.843562362 5.891626886 0 0 0 # ob 838 1 3 -1.050000 2.985008200 11.864367737 5.896222036 0 0 0 # ob 839 1 3 -1.050000 3.853629684 9.359090348 6.134239507 0 0 0 # ob 840 1 5 0.425000 -1.119111547 11.565705782 7.995024441 0 0 0 # ho 841 1 1 1.575000 6.106223722 10.281286664 9.189872068 0 0 0 # ao 842 1 2 2.100000 -10.547042805 -17.829737203 -6.523590700 1 1 1 # st 843 1 2 2.100000 -10.285373310 12.014671000 -6.517157818 1 0 1 # st 844 1 3 -1.050000 10.068798544 9.142788159 -8.141927041 0 0 1 # ob 845 1 3 -1.050000 -10.131862472 11.887172019 -8.139170101 1 0 1 # ob 846 1 4 -0.950000 7.908398214 10.855709216 -8.209932150 0 0 1 # oh 847 1 3 -1.050000 6.583130126 12.570994121 -5.905112111 0 0 1 # ob 848 1 3 -1.050000 -10.584171428 10.550188747 -5.909707262 1 0 1 # ob 849 1 3 -1.050000 9.187207088 13.055466135 -6.147724732 0 0 1 # ob 850 1 5 0.425000 8.999948471 10.848850702 -8.008509666 0 0 1 # ho 851 1 1 1.575000 -11.925608974 14.764197975 9.189872068 1 0 0 # ao 852 1 2 2.100000 7.710128565 13.550643561 -6.523590700 0 0 1 # st 853 1 2 2.100000 7.802794147 16.497582311 -6.517157818 0 0 1 # st 854 1 3 -1.050000 7.516966002 13.625699470 -8.141927041 0 0 1 # ob 855 1 3 -1.050000 7.956304986 16.370083330 -8.139170101 0 0 1 # ob 856 1 4 -0.950000 -10.123434482 15.338620527 -8.209932150 1 0 1 # oh 857 1 3 -1.050000 9.191297430 17.053905432 -5.905112111 0 0 1 # ob 858 1 3 -1.050000 7.503996030 15.033100058 -5.909707262 0 0 1 # ob 859 1 3 -1.050000 6.635374545 17.538377446 -6.147724732 0 0 1 # ob 860 1 5 0.425000 -9.031884224 15.331762013 -8.008509666 1 0 1 # ho 861 1 1 1.575000 6.148902607 16.252524607 9.189872068 0 0 0 # ao 862 1 2 2.100000 5.330708207 8.863912922 6.510105475 0 0 0 # st 863 1 2 2.100000 5.294377387 14.882796794 6.503672592 0 0 0 # st 864 1 3 -1.050000 5.354866857 -18.108612440 8.128441816 0 1 0 # ob 865 1 3 -1.050000 5.140866548 15.010295775 8.125684876 0 0 0 # ob 866 1 4 -0.950000 -12.899394137 16.041758578 8.196446925 1 0 0 # oh 867 1 3 -1.050000 -11.574126049 14.326473673 5.891626886 1 0 0 # ob 868 1 3 -1.050000 5.593175504 16.347279047 5.896222036 0 0 0 # ob 869 1 3 -1.050000 6.461796988 13.842001659 6.134239507 0 0 0 # ob 870 1 5 0.425000 6.649055605 16.048617092 7.995024441 0 0 0 # ho 871 1 1 1.575000 3.540735302 11.769613296 9.189872068 0 0 0 # ao 872 1 2 2.100000 -12.701124489 13.346824233 6.510105475 1 0 0 # st 873 1 2 2.100000 -12.793790070 10.399885483 6.503672592 1 0 0 # st 874 1 3 -1.050000 -12.507961925 13.271768324 8.128441816 1 0 0 # ob 875 1 3 -1.050000 -12.947300909 10.527384464 8.125684876 1 0 0 # ob 876 1 4 -0.950000 5.132438558 11.558847267 8.196446925 0 0 0 # oh 877 1 3 -1.050000 6.457706646 9.843562362 5.891626886 0 0 0 # ob 878 1 3 -1.050000 -12.494991953 11.864367737 5.896222036 1 0 0 # ob 879 1 3 -1.050000 -11.626370469 9.359090348 6.134239507 1 0 0 # ob 880 1 5 0.425000 4.040888301 11.565705782 7.995024441 0 0 0 # ho 881 1 1 1.575000 -9.373776431 10.281286664 9.189872068 1 0 0 # ao 882 1 2 2.100000 -5.387042958 -17.829737203 -6.523590700 1 1 1 # st 883 1 2 2.100000 -5.125373463 12.014671000 -6.517157818 1 0 1 # st 884 1 3 -1.050000 -5.411201608 9.142788159 -8.141927041 1 0 1 # ob 885 1 3 -1.050000 -4.971862624 11.887172019 -8.139170101 1 0 1 # ob 886 1 4 -0.950000 -7.571601939 10.855709216 -8.209932150 1 0 1 # oh 887 1 3 -1.050000 -8.896870027 12.570994121 -5.905112111 1 0 1 # ob 888 1 3 -1.050000 -5.424171580 10.550188747 -5.909707262 1 0 1 # ob 889 1 3 -1.050000 -6.292793064 13.055466135 -6.147724732 1 0 1 # ob 890 1 5 0.425000 -6.480051681 10.848850702 -8.008509666 1 0 1 # ho 891 1 1 1.575000 -6.765609126 14.764197975 9.189872068 1 0 0 # ao 892 1 2 2.100000 -7.769871587 13.550643561 -6.523590700 1 0 1 # st 893 1 2 2.100000 -7.677206006 16.497582311 -6.517157818 1 0 1 # st 894 1 3 -1.050000 -7.963034151 13.625699470 -8.141927041 1 0 1 # ob 895 1 3 -1.050000 -7.523695167 16.370083330 -8.139170101 1 0 1 # ob 896 1 4 -0.950000 -4.963434634 15.338620527 -8.209932150 1 0 1 # oh 897 1 3 -1.050000 -6.288702722 17.053905432 -5.905112111 1 0 1 # ob 898 1 3 -1.050000 -7.976004123 15.033100058 -5.909707262 1 0 1 # ob 899 1 3 -1.050000 -8.844625607 17.538377446 -6.147724732 1 0 1 # ob 900 1 5 0.425000 -3.871884377 15.331762013 -8.008509666 1 0 1 # ho 901 1 1 1.575000 -9.331097546 16.252524607 9.189872068 1 0 0 # ao 902 1 2 2.100000 -10.149291946 8.863912922 6.510105475 1 0 0 # st 903 1 2 2.100000 -10.185622766 14.882796794 6.503672592 1 0 0 # st 904 1 3 -1.050000 -10.125133295 -18.108612440 8.128441816 1 1 0 # ob 905 1 3 -1.050000 -10.339133604 15.010295775 8.125684876 1 0 0 # ob 906 1 4 -0.950000 -7.739394290 16.041758578 8.196446925 1 0 0 # oh 907 1 3 -1.050000 -6.414126201 14.326473673 5.891626886 1 0 0 # ob 908 1 3 -1.050000 -9.886824648 16.347279047 5.896222036 1 0 0 # ob 909 1 3 -1.050000 -9.018203164 13.842001659 6.134239507 1 0 0 # ob 910 1 5 0.425000 -8.830944547 16.048617092 7.995024441 1 0 0 # ho 911 1 1 1.575000 -11.939264850 11.769613296 9.189872068 1 0 0 # ao 912 1 2 2.100000 -7.541124641 13.346824233 6.510105475 1 0 0 # st 913 1 2 2.100000 -7.633790223 10.399885483 6.503672592 1 0 0 # st 914 1 3 -1.050000 -7.347962077 13.271768324 8.128441816 1 0 0 # ob 915 1 3 -1.050000 -7.787301062 10.527384464 8.125684876 1 0 0 # ob 916 1 4 -0.950000 -10.347561594 11.558847267 8.196446925 1 0 0 # oh 917 1 3 -1.050000 -9.022293506 9.843562362 5.891626886 1 0 0 # ob 918 1 3 -1.050000 -7.334992106 11.864367737 5.896222036 1 0 0 # ob 919 1 3 -1.050000 -6.466370621 9.359090348 6.134239507 1 0 0 # ob 920 1 5 0.425000 -11.439111852 11.565705782 7.995024441 1 0 0 # ho 921 1 1 1.575000 -4.213776583 10.281286664 9.189872068 1 0 0 # ao 922 1 2 2.100000 -0.227043110 -17.829737203 -6.523590700 1 1 1 # st 923 1 2 2.100000 0.034626385 12.014671000 -6.517157818 1 0 1 # st 924 1 3 -1.050000 -0.251201761 9.142788159 -8.141927041 1 0 1 # ob 925 1 3 -1.050000 0.188137223 11.887172019 -8.139170101 1 0 1 # ob 926 1 4 -0.950000 -2.411602091 10.855709216 -8.209932150 1 0 1 # oh 927 1 3 -1.050000 -3.736870180 12.570994121 -5.905112111 1 0 1 # ob 928 1 3 -1.050000 -0.264171733 10.550188747 -5.909707262 1 0 1 # ob 929 1 3 -1.050000 -1.132793217 13.055466135 -6.147724732 1 0 1 # ob 930 1 5 0.425000 -1.320051834 10.848850702 -8.008509666 1 0 1 # ho 931 1 1 1.575000 -1.605609279 14.764197975 9.189872068 1 0 0 # ao 932 1 2 2.100000 -2.609871740 13.550643561 -6.523590700 1 0 1 # st 933 1 2 2.100000 -2.517206158 16.497582311 -6.517157818 1 0 1 # st 934 1 3 -1.050000 -2.803034304 13.625699470 -8.141927041 1 0 1 # ob 935 1 3 -1.050000 -2.363695320 16.370083330 -8.139170101 1 0 1 # ob 936 1 4 -0.950000 0.196565213 15.338620527 -8.209932150 1 0 1 # oh 937 1 3 -1.050000 -1.128702875 17.053905432 -5.905112111 1 0 1 # ob 938 1 3 -1.050000 -2.816004275 15.033100058 -5.909707262 1 0 1 # ob 939 1 3 -1.050000 -3.684625760 17.538377446 -6.147724732 1 0 1 # ob 940 1 5 0.425000 1.288115471 15.331762013 -8.008509666 1 0 1 # ho 941 1 1 1.575000 -4.171097698 16.252524607 9.189872068 1 0 0 # ao 942 1 2 2.100000 -4.989292099 8.863912922 6.510105475 1 0 0 # st 943 1 2 2.100000 -5.025622918 14.882796794 6.503672592 1 0 0 # st 944 1 3 -1.050000 -4.965133448 -18.108612440 8.128441816 1 1 0 # ob 945 1 3 -1.050000 -5.179133757 15.010295775 8.125684876 1 0 0 # ob 946 1 4 -0.950000 -2.579394442 16.041758578 8.196446925 1 0 0 # oh 947 1 3 -1.050000 -1.254126354 14.326473673 5.891626886 1 0 0 # ob 948 1 3 -1.050000 -4.726824801 16.347279047 5.896222036 1 0 0 # ob 949 1 3 -1.050000 -3.858203317 13.842001659 6.134239507 1 0 0 # ob 950 1 5 0.425000 -3.670944700 16.048617092 7.995024441 1 0 0 # ho 951 1 1 1.575000 -6.779265003 11.769613296 9.189872068 1 0 0 # ao 952 1 2 2.100000 -2.381124794 13.346824233 6.510105475 1 0 0 # st 953 1 2 2.100000 -2.473790376 10.399885483 6.503672592 1 0 0 # st 954 1 3 -1.050000 -2.187962230 13.271768324 8.128441816 1 0 0 # ob 955 1 3 -1.050000 -2.627301214 10.527384464 8.125684876 1 0 0 # ob 956 1 4 -0.950000 -5.187561747 11.558847267 8.196446925 1 0 0 # oh 957 1 3 -1.050000 -3.862293659 9.843562362 5.891626886 1 0 0 # ob 958 1 3 -1.050000 -2.174992258 11.864367737 5.896222036 1 0 0 # ob 959 1 3 -1.050000 -1.306370774 9.359090348 6.134239507 1 0 0 # ob 960 1 5 0.425000 -6.279112005 11.565705782 7.995024441 1 0 0 # ho 961 1 1 1.575000 0.777219961 -16.616182789 9.189872068 0 1 0 # ao 962 1 2 2.100000 4.989292109 -8.863914582 -6.523590700 0 1 1 # st 963 1 2 2.100000 5.025622929 -14.882798454 -6.517157818 0 1 1 # st 964 1 3 -1.050000 4.739794784 -17.754681294 -8.141927041 0 1 1 # ob 965 1 3 -1.050000 5.179133768 -15.010297434 -8.139170101 0 1 1 # ob 966 1 4 -0.950000 2.579394453 -16.041760237 -8.209932150 0 1 1 # oh 967 1 3 -1.050000 1.254126365 -14.326475333 -5.905112111 0 1 1 # ob 968 1 3 -1.050000 4.726824812 -16.347280707 -5.909707262 0 1 1 # ob 969 1 3 -1.050000 3.858203328 -13.842003318 -6.147724732 0 1 1 # ob 970 1 5 0.425000 3.670944711 -16.048618752 -8.008509666 0 1 1 # ho 971 1 1 1.575000 3.385387266 -12.133271479 9.189872068 0 1 0 # ao 972 1 2 2.100000 2.381124805 -13.346825892 -6.523590700 0 1 1 # st 973 1 2 2.100000 2.473790386 -10.399887143 -6.517157818 0 1 1 # st 974 1 3 -1.050000 2.187962241 -13.271769983 -8.141927041 0 1 1 # ob 975 1 3 -1.050000 2.627301225 -10.527386123 -8.139170101 0 1 1 # ob 976 1 4 -0.950000 5.187561758 -11.558848927 -8.209932150 0 1 1 # oh 977 1 3 -1.050000 3.862293670 -9.843564022 -5.905112111 0 1 1 # ob 978 1 3 -1.050000 2.174992269 -11.864369396 -5.909707262 0 1 1 # ob 979 1 3 -1.050000 1.306370785 -9.359092007 -6.147724732 0 1 1 # ob 980 1 5 0.425000 6.279112015 -11.565707441 -8.008509666 0 1 1 # ho 981 1 1 1.575000 0.819898846 -10.644944847 9.189872068 0 1 0 # ao 982 1 2 2.100000 0.001704446 -18.033556531 6.510105475 0 1 0 # st 983 1 2 2.100000 -0.034626374 -12.014672659 6.503672592 0 1 0 # st 984 1 3 -1.050000 0.251201772 -9.142789819 8.128441816 0 1 0 # ob 985 1 3 -1.050000 -0.188137212 -11.887173679 8.125684876 0 1 0 # ob 986 1 4 -0.950000 2.411602102 -10.855710876 8.196446925 0 1 0 # oh 987 1 3 -1.050000 3.736870190 -12.570995780 5.891626886 0 1 0 # ob 988 1 3 -1.050000 0.264171744 -10.550190406 5.896222036 0 1 0 # ob 989 1 3 -1.050000 1.132793228 -13.055467795 6.134239507 0 1 0 # ob 990 1 5 0.425000 1.320051845 -10.848852361 7.995024441 0 1 0 # ho 991 1 1 1.575000 -1.788268458 -15.127856157 9.189872068 0 1 0 # ao 992 1 2 2.100000 2.609871751 -13.550645221 6.510105475 0 1 0 # st 993 1 2 2.100000 2.517206169 -16.497583970 6.503672592 0 1 0 # st 994 1 3 -1.050000 2.803034315 -13.625701130 8.128441816 0 1 0 # ob 995 1 3 -1.050000 2.363695330 -16.370084990 8.125684876 0 1 0 # ob 996 1 4 -0.950000 -0.196565202 -15.338622186 8.196446925 0 1 0 # oh 997 1 3 -1.050000 1.128702886 -17.053907091 5.891626886 0 1 0 # ob 998 1 3 -1.050000 2.816004286 -15.033101717 5.896222036 0 1 0 # ob 999 1 3 -1.050000 3.684625771 -17.538379106 6.134239507 0 1 0 # ob 1000 1 5 0.425000 -1.288115460 -15.331763672 7.995024441 0 1 0 # ho 1001 1 1 1.575000 5.937219808 -16.616182789 9.189872068 0 1 0 # ao 1002 1 2 2.100000 -10.490708043 -8.863914582 -6.523590700 1 1 1 # st 1003 1 2 2.100000 -10.454377223 -14.882798454 -6.517157818 1 1 1 # st 1004 1 3 -1.050000 9.899794631 -17.754681294 -8.141927041 0 1 1 # ob 1005 1 3 -1.050000 -10.300866385 -15.010297434 -8.139170101 1 1 1 # ob 1006 1 4 -0.950000 7.739394301 -16.041760237 -8.209932150 0 1 1 # oh 1007 1 3 -1.050000 6.414126212 -14.326475333 -5.905112111 0 1 1 # ob 1008 1 3 -1.050000 -10.753175341 -16.347280707 -5.909707262 1 1 1 # ob 1009 1 3 -1.050000 9.018203175 -13.842003318 -6.147724732 0 1 1 # ob 1010 1 5 0.425000 8.830944558 -16.048618752 -8.008509666 0 1 1 # ho 1011 1 1 1.575000 -12.094612887 -12.133271479 9.189872068 1 1 0 # ao 1012 1 2 2.100000 7.541124652 -13.346825892 -6.523590700 0 1 1 # st 1013 1 2 2.100000 7.633790234 -10.399887143 -6.517157818 0 1 1 # st 1014 1 3 -1.050000 7.347962088 -13.271769983 -8.141927041 0 1 1 # ob 1015 1 3 -1.050000 7.787301072 -10.527386123 -8.139170101 0 1 1 # ob 1016 1 4 -0.950000 -10.292438395 -11.558848927 -8.209932150 1 1 1 # oh 1017 1 3 -1.050000 9.022293517 -9.843564022 -5.905112111 0 1 1 # ob 1018 1 3 -1.050000 7.334992116 -11.864369396 -5.909707262 0 1 1 # ob 1019 1 3 -1.050000 6.466370632 -9.359092007 -6.147724732 0 1 1 # ob 1020 1 5 0.425000 -9.200888137 -11.565707441 -8.008509666 1 1 1 # ho 1021 1 1 1.575000 5.979898694 -10.644944847 9.189872068 0 1 0 # ao 1022 1 2 2.100000 5.161704293 -18.033556531 6.510105475 0 1 0 # st 1023 1 2 2.100000 5.125373474 -12.014672659 6.503672592 0 1 0 # st 1024 1 3 -1.050000 5.411201619 -9.142789819 8.128441816 0 1 0 # ob 1025 1 3 -1.050000 4.971862635 -11.887173679 8.125684876 0 1 0 # ob 1026 1 4 -0.950000 -13.068398050 -10.855710876 8.196446925 1 1 0 # oh 1027 1 3 -1.050000 -11.743129962 -12.570995780 5.891626886 1 1 0 # ob 1028 1 3 -1.050000 5.424171591 -10.550190406 5.896222036 0 1 0 # ob 1029 1 3 -1.050000 6.292793075 -13.055467795 6.134239507 0 1 0 # ob 1030 1 5 0.425000 6.480051692 -10.848852361 7.995024441 0 1 0 # ho 1031 1 1 1.575000 3.371731389 -15.127856157 9.189872068 0 1 0 # ao 1032 1 2 2.100000 -12.870128402 -13.550645221 6.510105475 1 1 0 # st 1033 1 2 2.100000 -12.962793984 -16.497583970 6.503672592 1 1 0 # st 1034 1 3 -1.050000 -12.676965838 -13.625701130 8.128441816 1 1 0 # ob 1035 1 3 -1.050000 -13.116304822 -16.370084990 8.125684876 1 1 0 # ob 1036 1 4 -0.950000 4.963434645 -15.338622186 8.196446925 0 1 0 # oh 1037 1 3 -1.050000 6.288702733 -17.053907091 5.891626886 0 1 0 # ob 1038 1 3 -1.050000 -12.663995866 -15.033101717 5.896222036 1 1 0 # ob 1039 1 3 -1.050000 -11.795374382 -17.538379106 6.134239507 1 1 0 # ob 1040 1 5 0.425000 3.871884387 -15.331763672 7.995024441 0 1 0 # ho 1041 1 1 1.575000 -9.542780344 -16.616182789 9.189872068 1 1 0 # ao 1042 1 2 2.100000 -5.330708196 -8.863914582 -6.523590700 1 1 1 # st 1043 1 2 2.100000 -5.294377376 -14.882798454 -6.517157818 1 1 1 # st 1044 1 3 -1.050000 -5.580205521 -17.754681294 -8.141927041 1 1 1 # ob 1045 1 3 -1.050000 -5.140866537 -15.010297434 -8.139170101 1 1 1 # ob 1046 1 4 -0.950000 -7.740605852 -16.041760237 -8.209932150 1 1 1 # oh 1047 1 3 -1.050000 -9.065873940 -14.326475333 -5.905112111 1 1 1 # ob 1048 1 3 -1.050000 -5.593175493 -16.347280707 -5.909707262 1 1 1 # ob 1049 1 3 -1.050000 -6.461796978 -13.842003318 -6.147724732 1 1 1 # ob 1050 1 5 0.425000 -6.649055594 -16.048618752 -8.008509666 1 1 1 # ho 1051 1 1 1.575000 -6.934613039 -12.133271479 9.189872068 1 1 0 # ao 1052 1 2 2.100000 -7.938875500 -13.346825892 -6.523590700 1 1 1 # st 1053 1 2 2.100000 -7.846209919 -10.399887143 -6.517157818 1 1 1 # st 1054 1 3 -1.050000 -8.132038064 -13.271769983 -8.141927041 1 1 1 # ob 1055 1 3 -1.050000 -7.692699080 -10.527386123 -8.139170101 1 1 1 # ob 1056 1 4 -0.950000 -5.132438547 -11.558848927 -8.209932150 1 1 1 # oh 1057 1 3 -1.050000 -6.457706636 -9.843564022 -5.905112111 1 1 1 # ob 1058 1 3 -1.050000 -8.145008036 -11.864369396 -5.909707262 1 1 1 # ob 1059 1 3 -1.050000 -9.013629520 -9.359092007 -6.147724732 1 1 1 # ob 1060 1 5 0.425000 -4.040888290 -11.565707441 -8.008509666 1 1 1 # ho 1061 1 1 1.575000 -9.500101459 -10.644944847 9.189872068 1 1 0 # ao 1062 1 2 2.100000 -10.318295859 -18.033556531 6.510105475 1 1 0 # st 1063 1 2 2.100000 -10.354626679 -12.014672659 6.503672592 1 1 0 # st 1064 1 3 -1.050000 -10.068798533 -9.142789819 8.128441816 1 1 0 # ob 1065 1 3 -1.050000 -10.508137518 -11.887173679 8.125684876 1 1 0 # ob 1066 1 4 -0.950000 -7.908398203 -10.855710876 8.196446925 1 1 0 # oh 1067 1 3 -1.050000 -6.583130115 -12.570995780 5.891626886 1 1 0 # ob 1068 1 3 -1.050000 -10.055828562 -10.550190406 5.896222036 1 1 0 # ob 1069 1 3 -1.050000 -9.187207077 -13.055467795 6.134239507 1 1 0 # ob 1070 1 5 0.425000 -8.999948461 -10.848852361 7.995024441 1 1 0 # ho 1071 1 1 1.575000 -12.108268763 -15.127856157 9.189872068 1 1 0 # ao 1072 1 2 2.100000 -7.710128554 -13.550645221 6.510105475 1 1 0 # st 1073 1 2 2.100000 -7.802794136 -16.497583970 6.503672592 1 1 0 # st 1074 1 3 -1.050000 -7.516965991 -13.625701130 8.128441816 1 1 0 # ob 1075 1 3 -1.050000 -7.956304975 -16.370084990 8.125684876 1 1 0 # ob 1076 1 4 -0.950000 -10.516565508 -15.338622186 8.196446925 1 1 0 # oh 1077 1 3 -1.050000 -9.191297419 -17.053907091 5.891626886 1 1 0 # ob 1078 1 3 -1.050000 -7.503996019 -15.033101717 5.896222036 1 1 0 # ob 1079 1 3 -1.050000 -6.635374534 -17.538379106 6.134239507 1 1 0 # ob 1080 1 5 0.425000 -11.608115765 -15.331763672 7.995024441 1 1 0 # ho 1081 1 1 1.575000 -4.382780497 -16.616182789 9.189872068 1 1 0 # ao 1082 1 2 2.100000 -0.170708348 -8.863914582 -6.523590700 1 1 1 # st 1083 1 2 2.100000 -0.134377529 -14.882798454 -6.517157818 1 1 1 # st 1084 1 3 -1.050000 -0.420205674 -17.754681294 -8.141927041 1 1 1 # ob 1085 1 3 -1.050000 0.019133310 -15.010297434 -8.139170101 1 1 1 # ob 1086 1 4 -0.950000 -2.580606005 -16.041760237 -8.209932150 1 1 1 # oh 1087 1 3 -1.050000 -3.905874093 -14.326475333 -5.905112111 1 1 1 # ob 1088 1 3 -1.050000 -0.433175646 -16.347280707 -5.909707262 1 1 1 # ob 1089 1 3 -1.050000 -1.301797130 -13.842003318 -6.147724732 1 1 1 # ob 1090 1 5 0.425000 -1.489055747 -16.048618752 -8.008509666 1 1 1 # ho 1091 1 1 1.575000 -1.774613192 -12.133271479 9.189872068 1 1 0 # ao 1092 1 2 2.100000 -2.778875653 -13.346825892 -6.523590700 1 1 1 # st 1093 1 2 2.100000 -2.686210071 -10.399887143 -6.517157818 1 1 1 # st 1094 1 3 -1.050000 -2.972038217 -13.271769983 -8.141927041 1 1 1 # ob 1095 1 3 -1.050000 -2.532699233 -10.527386123 -8.139170101 1 1 1 # ob 1096 1 4 -0.950000 0.027561300 -11.558848927 -8.209932150 1 1 1 # oh 1097 1 3 -1.050000 -1.297706788 -9.843564022 -5.905112111 1 1 1 # ob 1098 1 3 -1.050000 -2.985008189 -11.864369396 -5.909707262 1 1 1 # ob 1099 1 3 -1.050000 -3.853629673 -9.359092007 -6.147724732 1 1 1 # ob 1100 1 5 0.425000 1.119111558 -11.565707441 -8.008509666 1 1 1 # ho 1101 1 1 1.575000 -4.340101611 -10.644944847 9.189872068 1 1 0 # ao 1102 1 2 2.100000 -5.158296012 -18.033556531 6.510105475 1 1 0 # st 1103 1 2 2.100000 -5.194626832 -12.014672659 6.503672592 1 1 0 # st 1104 1 3 -1.050000 -4.908798686 -9.142789819 8.128441816 1 1 0 # ob 1105 1 3 -1.050000 -5.348137670 -11.887173679 8.125684876 1 1 0 # ob 1106 1 4 -0.950000 -2.748398356 -10.855710876 8.196446925 1 1 0 # oh 1107 1 3 -1.050000 -1.423130267 -12.570995780 5.891626886 1 1 0 # ob 1108 1 3 -1.050000 -4.895828714 -10.550190406 5.896222036 1 1 0 # ob 1109 1 3 -1.050000 -4.027207230 -13.055467795 6.134239507 1 1 0 # ob 1110 1 5 0.425000 -3.839948613 -10.848852361 7.995024441 1 1 0 # ho 1111 1 1 1.575000 -6.948268916 -15.127856157 9.189872068 1 1 0 # ao 1112 1 2 2.100000 -2.550128707 -13.550645221 6.510105475 1 1 0 # st 1113 1 2 2.100000 -2.642794289 -16.497583970 6.503672592 1 1 0 # st 1114 1 3 -1.050000 -2.356966143 -13.625701130 8.128441816 1 1 0 # ob 1115 1 3 -1.050000 -2.796305127 -16.370084990 8.125684876 1 1 0 # ob 1116 1 4 -0.950000 -5.356565660 -15.338622186 8.196446925 1 1 0 # oh 1117 1 3 -1.050000 -4.031297572 -17.053907091 5.891626886 1 1 0 # ob 1118 1 3 -1.050000 -2.343996171 -15.033101717 5.896222036 1 1 0 # ob 1119 1 3 -1.050000 -1.475374687 -17.538379106 6.134239507 1 1 0 # ob 1120 1 5 0.425000 -6.448115918 -15.331763672 7.995024441 1 1 0 # ho 1121 1 1 1.575000 0.833554723 -7.650360168 9.189872068 0 1 0 # ao 1122 1 2 2.100000 5.045626871 0.101908040 -6.523590700 0 1 1 # st 1123 1 2 2.100000 5.081957691 -5.916975832 -6.517157818 0 1 1 # st 1124 1 3 -1.050000 4.796129546 -8.788858673 -8.141927041 0 1 1 # ob 1125 1 3 -1.050000 5.235468530 -6.044474812 -8.139170101 0 1 1 # ob 1126 1 4 -0.950000 2.635729215 -7.075937616 -8.209932150 0 1 1 # oh 1127 1 3 -1.050000 1.310461127 -5.360652711 -5.905112111 0 1 1 # ob 1128 1 3 -1.050000 4.783159574 -7.381458085 -5.909707262 0 1 1 # ob 1129 1 3 -1.050000 3.914538089 -4.876180697 -6.147724732 0 1 1 # ob 1130 1 5 0.425000 3.727279473 -7.082796130 -8.008509666 0 1 1 # ho 1131 1 1 1.575000 3.441722028 -3.167448857 9.189872068 0 1 0 # ao 1132 1 2 2.100000 2.437459567 -4.381003271 -6.523590700 0 1 1 # st 1133 1 2 2.100000 2.530125148 -1.434064521 -6.517157818 0 1 1 # st 1134 1 3 -1.050000 2.244297003 -4.305947362 -8.141927041 0 1 1 # ob 1135 1 3 -1.050000 2.683635987 -1.561563502 -8.139170101 0 1 1 # ob 1136 1 4 -0.950000 5.243896520 -2.593026305 -8.209932150 0 1 1 # oh 1137 1 3 -1.050000 3.918628431 -0.877741400 -5.905112111 0 1 1 # ob 1138 1 3 -1.050000 2.231327031 -2.898546774 -5.909707262 0 1 1 # ob 1139 1 3 -1.050000 1.362705547 -0.393269386 -6.147724732 0 1 1 # ob 1140 1 5 0.425000 6.335446777 -2.599884819 -8.008509666 0 1 1 # ho 1141 1 1 1.575000 0.876233608 -1.679122225 9.189872068 0 1 0 # ao 1142 1 2 2.100000 0.058039208 -9.067733910 6.510105475 0 1 0 # st 1143 1 2 2.100000 0.021708388 -3.048850038 6.503672592 0 1 0 # st 1144 1 3 -1.050000 0.307536534 -0.176967197 8.128441816 0 1 0 # ob 1145 1 3 -1.050000 -0.131802451 -2.921351057 8.125684876 0 1 0 # ob 1146 1 4 -0.950000 2.467936864 -1.889888254 8.196446925 0 1 0 # oh 1147 1 3 -1.050000 3.793204952 -3.605173159 5.891626886 0 1 0 # ob 1148 1 3 -1.050000 0.320506505 -1.584367785 5.896222036 0 1 0 # ob 1149 1 3 -1.050000 1.189127990 -4.089645173 6.134239507 0 1 0 # ob 1150 1 5 0.425000 1.376386606 -1.883029740 7.995024441 0 1 0 # ho 1151 1 1 1.575000 -1.731933696 -6.162033536 9.189872068 0 1 0 # ao 1152 1 2 2.100000 2.666206512 -4.584822599 6.510105475 0 1 0 # st 1153 1 2 2.100000 2.573540931 -7.531761349 6.503672592 0 1 0 # st 1154 1 3 -1.050000 2.859369076 -4.659878508 8.128441816 0 1 0 # ob 1155 1 3 -1.050000 2.420030092 -7.404262368 8.125684876 0 1 0 # ob 1156 1 4 -0.950000 -0.140230441 -6.372799565 8.196446925 0 1 0 # oh 1157 1 3 -1.050000 1.185037648 -8.088084470 5.891626886 0 1 0 # ob 1158 1 3 -1.050000 2.872339048 -6.067279095 5.896222036 0 1 0 # ob 1159 1 3 -1.050000 3.740960532 -8.572556484 6.134239507 0 1 0 # ob 1160 1 5 0.425000 -1.231780698 -6.365941050 7.995024441 0 1 0 # ho 1161 1 1 1.575000 5.993554570 -7.650360168 9.189872068 0 1 0 # ao 1162 1 2 2.100000 -10.434373281 0.101908040 -6.523590700 1 1 1 # st 1163 1 2 2.100000 -10.398042462 -5.916975832 -6.517157818 1 1 1 # st 1164 1 3 -1.050000 9.956129393 -8.788858673 -8.141927041 0 1 1 # ob 1165 1 3 -1.050000 -10.244531623 -6.044474812 -8.139170101 1 1 1 # ob 1166 1 4 -0.950000 7.795729062 -7.075937616 -8.209932150 0 1 1 # oh 1167 1 3 -1.050000 6.470460974 -5.360652711 -5.905112111 0 1 1 # ob 1168 1 3 -1.050000 -10.696840579 -7.381458085 -5.909707262 1 1 1 # ob 1169 1 3 -1.050000 9.074537937 -4.876180697 -6.147724732 0 1 1 # ob 1170 1 5 0.425000 8.887279320 -7.082796130 -8.008509666 0 1 1 # ho 1171 1 1 1.575000 -12.038278125 -3.167448857 9.189872068 1 1 0 # ao 1172 1 2 2.100000 7.597459414 -4.381003271 -6.523590700 0 1 1 # st 1173 1 2 2.100000 7.690124996 -1.434064521 -6.517157818 0 1 1 # st 1174 1 3 -1.050000 7.404296850 -4.305947362 -8.141927041 0 1 1 # ob 1175 1 3 -1.050000 7.843635834 -1.561563502 -8.139170101 0 1 1 # ob 1176 1 4 -0.950000 -10.236103633 -2.593026305 -8.209932150 1 1 1 # oh 1177 1 3 -1.050000 9.078628279 -0.877741400 -5.905112111 0 1 1 # ob 1178 1 3 -1.050000 7.391326878 -2.898546774 -5.909707262 0 1 1 # ob 1179 1 3 -1.050000 6.522705394 -0.393269386 -6.147724732 0 1 1 # ob 1180 1 5 0.425000 -9.144553375 -2.599884819 -8.008509666 1 1 1 # ho 1181 1 1 1.575000 6.036233456 -1.679122225 9.189872068 0 1 0 # ao 1182 1 2 2.100000 5.218039055 -9.067733910 6.510105475 0 1 0 # st 1183 1 2 2.100000 5.181708235 -3.048850038 6.503672592 0 1 0 # st 1184 1 3 -1.050000 5.467536381 -0.176967197 8.128441816 0 1 0 # ob 1185 1 3 -1.050000 5.028197397 -2.921351057 8.125684876 0 1 0 # ob 1186 1 4 -0.950000 -13.012063289 -1.889888254 8.196446925 1 1 0 # oh 1187 1 3 -1.050000 -11.686795200 -3.605173159 5.891626886 1 1 0 # ob 1188 1 3 -1.050000 5.480506353 -1.584367785 5.896222036 0 1 0 # ob 1189 1 3 -1.050000 6.349127837 -4.089645173 6.134239507 0 1 0 # ob 1190 1 5 0.425000 6.536386454 -1.883029740 7.995024441 0 1 0 # ho 1191 1 1 1.575000 3.428066151 -6.162033536 9.189872068 0 1 0 # ao 1192 1 2 2.100000 -12.813793640 -4.584822599 6.510105475 1 1 0 # st 1193 1 2 2.100000 -12.906459222 -7.531761349 6.503672592 1 1 0 # st 1194 1 3 -1.050000 -12.620631076 -4.659878508 8.128441816 1 1 0 # ob 1195 1 3 -1.050000 -13.059970060 -7.404262368 8.125684876 1 1 0 # ob 1196 1 4 -0.950000 5.019769407 -6.372799565 8.196446925 0 1 0 # oh 1197 1 3 -1.050000 6.345037495 -8.088084470 5.891626886 0 1 0 # ob 1198 1 3 -1.050000 -12.607661104 -6.067279095 5.896222036 1 1 0 # ob 1199 1 3 -1.050000 -11.739039620 -8.572556484 6.134239507 1 1 0 # ob 1200 1 5 0.425000 3.928219149 -6.365941050 7.995024441 0 1 0 # ho 1201 1 1 1.575000 -9.486445582 -7.650360168 9.189872068 1 1 0 # ao 1202 1 2 2.100000 -5.274373434 0.101908040 -6.523590700 1 1 1 # st 1203 1 2 2.100000 -5.238042614 -5.916975832 -6.517157818 1 1 1 # st 1204 1 3 -1.050000 -5.523870760 -8.788858673 -8.141927041 1 1 1 # ob 1205 1 3 -1.050000 -5.084531776 -6.044474812 -8.139170101 1 1 1 # ob 1206 1 4 -0.950000 -7.684271090 -7.075937616 -8.209932150 1 1 1 # oh 1207 1 3 -1.050000 -9.009539178 -5.360652711 -5.905112111 1 1 1 # ob 1208 1 3 -1.050000 -5.536840731 -7.381458085 -5.909707262 1 1 1 # ob 1209 1 3 -1.050000 -6.405462216 -4.876180697 -6.147724732 1 1 1 # ob 1210 1 5 0.425000 -6.592720833 -7.082796130 -8.008509666 1 1 1 # ho 1211 1 1 1.575000 -6.878278278 -3.167448857 9.189872068 1 1 0 # ao 1212 1 2 2.100000 -7.882540739 -4.381003271 -6.523590700 1 1 1 # st 1213 1 2 2.100000 -7.789875157 -1.434064521 -6.517157818 1 1 1 # st 1214 1 3 -1.050000 -8.075703302 -4.305947362 -8.141927041 1 1 1 # ob 1215 1 3 -1.050000 -7.636364318 -1.561563502 -8.139170101 1 1 1 # ob 1216 1 4 -0.950000 -5.076103786 -2.593026305 -8.209932150 1 1 1 # oh 1217 1 3 -1.050000 -6.401371874 -0.877741400 -5.905112111 1 1 1 # ob 1218 1 3 -1.050000 -8.088673274 -2.898546774 -5.909707262 1 1 1 # ob 1219 1 3 -1.050000 -8.957294759 -0.393269386 -6.147724732 1 1 1 # ob 1220 1 5 0.425000 -3.984553528 -2.599884819 -8.008509666 1 1 1 # ho 1221 1 1 1.575000 -9.443766697 -1.679122225 9.189872068 1 1 0 # ao 1222 1 2 2.100000 -10.261961097 -9.067733910 6.510105475 1 1 0 # st 1223 1 2 2.100000 -10.298291917 -3.048850038 6.503672592 1 1 0 # st 1224 1 3 -1.050000 -10.012463772 -0.176967197 8.128441816 1 1 0 # ob 1225 1 3 -1.050000 -10.451802756 -2.921351057 8.125684876 1 1 0 # ob 1226 1 4 -0.950000 -7.852063441 -1.889888254 8.196446925 1 1 0 # oh 1227 1 3 -1.050000 -6.526795353 -3.605173159 5.891626886 1 1 0 # ob 1228 1 3 -1.050000 -9.999493800 -1.584367785 5.896222036 1 1 0 # ob 1229 1 3 -1.050000 -9.130872315 -4.089645173 6.134239507 1 1 0 # ob 1230 1 5 0.425000 -8.943613699 -1.883029740 7.995024441 1 1 0 # ho 1231 1 1 1.575000 -12.051934002 -6.162033536 9.189872068 1 1 0 # ao 1232 1 2 2.100000 -7.653793793 -4.584822599 6.510105475 1 1 0 # st 1233 1 2 2.100000 -7.746459374 -7.531761349 6.503672592 1 1 0 # st 1234 1 3 -1.050000 -7.460631229 -4.659878508 8.128441816 1 1 0 # ob 1235 1 3 -1.050000 -7.899970213 -7.404262368 8.125684876 1 1 0 # ob 1236 1 4 -0.950000 -10.460230746 -6.372799565 8.196446925 1 1 0 # oh 1237 1 3 -1.050000 -9.134962657 -8.088084470 5.891626886 1 1 0 # ob 1238 1 3 -1.050000 -7.447661257 -6.067279095 5.896222036 1 1 0 # ob 1239 1 3 -1.050000 -6.579039773 -8.572556484 6.134239507 1 1 0 # ob 1240 1 5 0.425000 -11.551781003 -6.365941050 7.995024441 1 1 0 # ho 1241 1 1 1.575000 -4.326445735 -7.650360168 9.189872068 1 1 0 # ao 1242 1 2 2.100000 -0.114373587 0.101908040 -6.523590700 1 1 1 # st 1243 1 2 2.100000 -0.078042767 -5.916975832 -6.517157818 1 1 1 # st 1244 1 3 -1.050000 -0.363870912 -8.788858673 -8.141927041 1 1 1 # ob 1245 1 3 -1.050000 0.075468072 -6.044474812 -8.139170101 1 1 1 # ob 1246 1 4 -0.950000 -2.524271243 -7.075937616 -8.209932150 1 1 1 # oh 1247 1 3 -1.050000 -3.849539331 -5.360652711 -5.905112111 1 1 1 # ob 1248 1 3 -1.050000 -0.376840884 -7.381458085 -5.909707262 1 1 1 # ob 1249 1 3 -1.050000 -1.245462368 -4.876180697 -6.147724732 1 1 1 # ob 1250 1 5 0.425000 -1.432720985 -7.082796130 -8.008509666 1 1 1 # ho 1251 1 1 1.575000 -1.718278430 -3.167448857 9.189872068 1 1 0 # ao 1252 1 2 2.100000 -2.722540891 -4.381003271 -6.523590700 1 1 1 # st 1253 1 2 2.100000 -2.629875310 -1.434064521 -6.517157818 1 1 1 # st 1254 1 3 -1.050000 -2.915703455 -4.305947362 -8.141927041 1 1 1 # ob 1255 1 3 -1.050000 -2.476364471 -1.561563502 -8.139170101 1 1 1 # ob 1256 1 4 -0.950000 0.083896062 -2.593026305 -8.209932150 1 1 1 # oh 1257 1 3 -1.050000 -1.241372026 -0.877741400 -5.905112111 1 1 1 # ob 1258 1 3 -1.050000 -2.928673427 -2.898546774 -5.909707262 1 1 1 # ob 1259 1 3 -1.050000 -3.797294911 -0.393269386 -6.147724732 1 1 1 # ob 1260 1 5 0.425000 1.175446320 -2.599884819 -8.008509666 1 1 1 # ho 1261 1 1 1.575000 -4.283766850 -1.679122225 9.189872068 1 1 0 # ao 1262 1 2 2.100000 -5.101961250 -9.067733910 6.510105475 1 1 0 # st 1263 1 2 2.100000 -5.138292070 -3.048850038 6.503672592 1 1 0 # st 1264 1 3 -1.050000 -4.852463924 -0.176967197 8.128441816 1 1 0 # ob 1265 1 3 -1.050000 -5.291802908 -2.921351057 8.125684876 1 1 0 # ob 1266 1 4 -0.950000 -2.692063594 -1.889888254 8.196446925 1 1 0 # oh 1267 1 3 -1.050000 -1.366795505 -3.605173159 5.891626886 1 1 0 # ob 1268 1 3 -1.050000 -4.839493952 -1.584367785 5.896222036 1 1 0 # ob 1269 1 3 -1.050000 -3.970872468 -4.089645173 6.134239507 1 1 0 # ob 1270 1 5 0.425000 -3.783613851 -1.883029740 7.995024441 1 1 0 # ho 1271 1 1 1.575000 -6.891934154 -6.162033536 9.189872068 1 1 0 # ao 1272 1 2 2.100000 -2.493793945 -4.584822599 6.510105475 1 1 0 # st 1273 1 2 2.100000 -2.586459527 -7.531761349 6.503672592 1 1 0 # st 1274 1 3 -1.050000 -2.300631381 -4.659878508 8.128441816 1 1 0 # ob 1275 1 3 -1.050000 -2.739970366 -7.404262368 8.125684876 1 1 0 # ob 1276 1 4 -0.950000 -5.300230898 -6.372799565 8.196446925 1 1 0 # oh 1277 1 3 -1.050000 -3.974962810 -8.088084470 5.891626886 1 1 0 # ob 1278 1 3 -1.050000 -2.287661410 -6.067279095 5.896222036 1 1 0 # ob 1279 1 3 -1.050000 -1.419039925 -8.572556484 6.134239507 1 1 0 # ob 1280 1 5 0.425000 -6.391781156 -6.365941050 7.995024441 1 1 0 # ho Bonds 1 1 6 10 2 1 16 20 3 1 26 30 4 1 36 40 5 1 46 50 6 1 56 60 7 1 66 70 8 1 76 80 9 1 86 90 10 1 96 100 11 1 106 110 12 1 116 120 13 1 126 130 14 1 136 140 15 1 146 150 16 1 156 160 17 1 166 170 18 1 176 180 19 1 186 190 20 1 196 200 21 1 206 210 22 1 216 220 23 1 226 230 24 1 236 240 25 1 246 250 26 1 256 260 27 1 266 270 28 1 276 280 29 1 286 290 30 1 296 300 31 1 306 310 32 1 316 320 33 1 326 330 34 1 336 340 35 1 346 350 36 1 356 360 37 1 366 370 38 1 376 380 39 1 386 390 40 1 396 400 41 1 406 410 42 1 416 420 43 1 426 430 44 1 436 440 45 1 446 450 46 1 456 460 47 1 466 470 48 1 476 480 49 1 486 490 50 1 496 500 51 1 506 510 52 1 516 520 53 1 526 530 54 1 536 540 55 1 546 550 56 1 556 560 57 1 566 570 58 1 576 580 59 1 586 590 60 1 596 600 61 1 606 610 62 1 616 620 63 1 626 630 64 1 636 640 65 1 646 650 66 1 656 660 67 1 666 670 68 1 676 680 69 1 686 690 70 1 696 700 71 1 706 710 72 1 716 720 73 1 726 730 74 1 736 740 75 1 746 750 76 1 756 760 77 1 766 770 78 1 776 780 79 1 786 790 80 1 796 800 81 1 806 810 82 1 816 820 83 1 826 830 84 1 836 840 85 1 846 850 86 1 856 860 87 1 866 870 88 1 876 880 89 1 886 890 90 1 896 900 91 1 906 910 92 1 916 920 93 1 926 930 94 1 936 940 95 1 946 950 96 1 956 960 97 1 966 970 98 1 976 980 99 1 986 990 100 1 996 1000 101 1 1006 1010 102 1 1016 1020 103 1 1026 1030 104 1 1036 1040 105 1 1046 1050 106 1 1056 1060 107 1 1066 1070 108 1 1076 1080 109 1 1086 1090 110 1 1096 1100 111 1 1106 1110 112 1 1116 1120 113 1 1126 1130 114 1 1136 1140 115 1 1146 1150 116 1 1156 1160 117 1 1166 1170 118 1 1176 1180 119 1 1186 1190 120 1 1196 1200 121 1 1206 1210 122 1 1216 1220 123 1 1226 1230 124 1 1236 1240 125 1 1246 1250 126 1 1256 1260 127 1 1266 1270 128 1 1276 1280 diff --git a/tools/msi2lmp/test/reference/PyAC_bulk-clayff.data2 b/tools/msi2lmp/test/reference/PyAC_bulk-clayff.data2 index c1ad8d0a1..4ee3c34e0 100644 --- a/tools/msi2lmp/test/reference/PyAC_bulk-clayff.data2 +++ b/tools/msi2lmp/test/reference/PyAC_bulk-clayff.data2 @@ -1,2728 +1,2728 @@ -LAMMPS data file via write_data, version 24 Oct 2015-ICMS, timestep = 97 +LAMMPS data file via write_data, version 5 Oct 2016, timestep = 97 1280 atoms 5 atom types 128 bonds 1 bond types -1.0320000000000000e+01 1.0320000000000000e+01 xlo xhi -1.7931646038000000e+01 1.7931646038000000e+01 ylo yhi -9.1966146809999998e+00 9.1966146809999998e+00 zlo zhi 2.2533867499999999e-01 -3.3938777480000000e+00 -3.6365652300000001e-01 xy xz yz Masses 1 26.9815 2 28.0855 3 15.9994 4 15.9994 5 1.00797 Pair Coeffs # lj/cut/coul/long 1 1.3297e-06 4.27132 2 1.8402e-06 3.30196 3 0.155416 3.16552 4 0.155416 3.16552 5 0 0 Bond Coeffs # harmonic 1 553.935 1 Atoms # full -1 1 1 1.5750000000000000e+00 2.6000714789593751e+00 1.4894792160606976e+00 -3.2724341643746158e-03 0 0 0 -2 1 2 2.1000000000000001e+00 3.3888512764168830e+00 8.8633039168875207e+00 2.7538958890238696e+00 0 0 0 -3 1 2 2.1000000000000001e+00 3.4122036402903841e+00 2.8524887294223298e+00 2.7617665793809874e+00 0 0 0 -4 1 3 -1.0500000000000000e+00 3.1915227275702804e+00 -3.1324495771823280e-02 1.1357360737372577e+00 0 0 0 -5 1 3 -1.0500000000000000e+00 3.5470332310491468e+00 2.7594471461919454e+00 1.1370452762630130e+00 0 0 0 -6 1 4 -9.4999999999999996e-01 9.0639639057410193e-01 1.5632155125620351e+00 1.0068888079392266e+00 0 0 0 -7 1 3 -1.0500000000000000e+00 -4.4300615993295267e-01 3.5553766737673556e+00 3.2357435343452252e+00 0 0 0 -8 1 3 -1.0500000000000000e+00 3.2999227287331738e+00 1.3781331597446389e+00 3.2376888080414368e+00 0 0 0 -9 1 3 -1.0500000000000000e+00 2.1466799995253449e+00 3.7042086116993893e+00 3.0458513707542529e+00 0 0 0 -10 1 5 4.2499999999999999e-01 3.9947470817457997e-01 6.8417215087817951e-01 1.1506443642559319e+00 0 0 0 -11 1 1 1.5750000000000000e+00 5.2082449841408476e+00 5.9724138174009802e+00 -3.2727950796616057e-03 0 0 0 -12 1 2 2.1000000000000001e+00 7.8065894330936025e-01 4.3803928207698632e+00 2.7538963739148841e+00 0 0 0 -13 1 2 2.1000000000000001e+00 8.6037969207801268e-01 7.3353752959374141e+00 2.7617620870872734e+00 0 0 0 -14 1 3 -1.0500000000000000e+00 6.3966639689459548e-01 4.4515687682101515e+00 1.1357627423737586e+00 0 0 0 -15 1 3 -1.0500000000000000e+00 9.9522811059404503e-01 7.2423309133503437e+00 1.1370279152922151e+00 0 0 0 -16 1 4 -9.4999999999999996e-01 3.5145746331402776e+00 6.0461056209184996e+00 1.0068980245516883e+00 0 0 0 -17 1 3 -1.0500000000000000e+00 2.1651871307123436e+00 8.0382769067536834e+00 3.2357639695907174e+00 0 0 0 -18 1 3 -1.0500000000000000e+00 7.4808571963755277e-01 5.8610699261249799e+00 3.2376852068400783e+00 0 0 0 -19 1 3 -1.0500000000000000e+00 -4.0513200105762692e-01 8.1871458861348252e+00 3.0458340831318527e+00 0 0 0 -20 1 5 4.2499999999999999e-01 3.0076408529876133e+00 5.1671352838070419e+00 1.1506727018101763e+00 0 0 0 -21 1 1 1.5750000000000000e+00 2.6160337242627385e+00 7.4762121163480835e+00 -3.7679339507690202e-03 0 0 0 -22 1 2 2.1000000000000001e+00 1.8272442423721067e+00 1.0235452397406419e-01 -2.7608951598863420e+00 0 0 0 -23 1 2 2.1000000000000001e+00 1.8039149824855656e+00 6.1131988863851205e+00 -2.7688143987069944e+00 0 0 0 -24 1 3 -1.0500000000000000e+00 2.0247359072770106e+00 8.9971166431897238e+00 -1.1428135308481817e+00 0 0 0 -25 1 3 -1.0500000000000000e+00 1.6690396934061837e+00 6.2060610243661216e+00 -1.1440123480308522e+00 0 0 0 -26 1 4 -9.4999999999999996e-01 4.3098171216561010e+00 7.4025604980703399e+00 -1.0139209840264627e+00 0 0 0 -27 1 3 -1.0500000000000000e+00 5.6591538061328155e+00 5.4102822214207755e+00 -3.2426109985712959e+00 0 0 0 -28 1 3 -1.0500000000000000e+00 1.9163543145814046e+00 7.5875429044875240e+00 -3.2448378878070452e+00 0 0 0 -29 1 3 -1.0500000000000000e+00 3.0694016918821738e+00 5.2613972898578716e+00 -3.0528608543594498e+00 0 0 0 -30 1 5 4.2499999999999999e-01 4.8166238332644706e+00 8.2814552559221255e+00 -1.1575484564914529e+00 0 0 0 -31 1 1 1.5750000000000000e+00 7.8721152905387726e-03 2.9932710911072924e+00 -3.7631068242820476e-03 0 0 0 -32 1 2 2.1000000000000001e+00 4.4354124124076613e+00 4.5852699365916116e+00 -2.7608937131000477e+00 0 0 0 -33 1 2 2.1000000000000001e+00 4.3557271097076509e+00 1.6303240475520013e+00 -2.7688126814472618e+00 0 0 0 -34 1 3 -1.0500000000000000e+00 4.5765848686916186e+00 4.5142288488406983e+00 -1.1428174767092045e+00 0 0 0 -35 1 3 -1.0500000000000000e+00 4.2208490378864258e+00 1.7231665684011759e+00 -1.1440027470792096e+00 0 0 0 -36 1 4 -9.4999999999999996e-01 1.7016187601541688e+00 2.9196493272429898e+00 -1.0139413773039561e+00 0 0 0 -37 1 3 -1.0500000000000000e+00 3.0509330899831255e+00 9.2736403559655045e-01 -3.2426261785942208e+00 0 0 0 -38 1 3 -1.0500000000000000e+00 4.4681918905758522e+00 3.1045919000279127e+00 -3.2448481471079784e+00 0 0 0 -39 1 3 -1.0500000000000000e+00 5.6212256650052446e+00 7.7845330241011723e-01 -3.0528452687877392e+00 0 0 0 -40 1 5 4.2499999999999999e-01 2.2084407067451135e+00 3.7984879157614522e+00 -1.1576655468405033e+00 0 0 0 -41 1 1 1.5750000000000000e+00 7.7600845308154121e+00 1.4894705806920072e+00 -3.2671351978219576e-03 0 0 0 -42 1 2 2.1000000000000001e+00 -1.2091142634891035e+01 8.8633145054206288e+00 2.7538808736094804e+00 1 0 0 -43 1 2 2.1000000000000001e+00 -1.2067805176309086e+01 2.8524796084808841e+00 2.7617740243776367e+00 1 0 0 -44 1 3 -1.0500000000000000e+00 8.3515069292543487e+00 -3.1325720205767738e-02 1.1357488996139420e+00 0 0 0 -45 1 3 -1.0500000000000000e+00 -1.1932961924224253e+01 2.7594497009075667e+00 1.1370388175604429e+00 1 0 0 -46 1 4 -9.4999999999999996e-01 6.0663707264653013e+00 1.5631845173515728e+00 1.0068709132216025e+00 0 0 0 -47 1 3 -1.0500000000000000e+00 4.7169659967870281e+00 3.5553592839706596e+00 3.2357488556419618e+00 0 0 0 -48 1 3 -1.0500000000000000e+00 -1.2180080803394853e+01 1.3781323790369449e+00 3.2377056231325412e+00 1 0 0 -49 1 3 -1.0500000000000000e+00 7.3066640290441995e+00 3.7042200322170231e+00 3.0458484110925532e+00 0 0 0 -50 1 5 4.2499999999999999e-01 5.5594541328557323e+00 6.8415109182854295e-01 1.1505002465261160e+00 0 0 0 -51 1 1 1.5750000000000000e+00 -1.0271746834233385e+01 5.9724140268693553e+00 -3.2716143612443460e-03 1 0 0 -52 1 2 2.1000000000000001e+00 5.9406816112148135e+00 4.3803846602753786e+00 2.7538960010783704e+00 0 0 0 -53 1 2 2.1000000000000001e+00 6.0203901170690983e+00 7.3353651695314888e+00 2.7617667261366279e+00 0 0 0 -54 1 3 -1.0500000000000000e+00 5.7996709988339532e+00 4.4515666071358559e+00 1.1357461524365906e+00 0 0 0 -55 1 3 -1.0500000000000000e+00 6.1552236861599425e+00 7.2423398264353658e+00 1.1370349087014215e+00 0 0 0 -56 1 4 -9.4999999999999996e-01 -1.1965418454563789e+01 6.0461212882123156e+00 1.0069140277775315e+00 1 0 0 -57 1 3 -1.0500000000000000e+00 7.3251652456970113e+00 8.0382592725304569e+00 3.2357579104016239e+00 0 0 0 -58 1 3 -1.0500000000000000e+00 5.9080869344973941e+00 5.8610858948570197e+00 3.2376917279590067e+00 0 0 0 -59 1 3 -1.0500000000000000e+00 4.7548544779284576e+00 8.1871510262123515e+00 3.0458361561728324e+00 0 0 0 -60 1 5 4.2499999999999999e-01 8.1676630487137487e+00 5.1671484741634544e+00 1.1507863408329566e+00 0 0 0 -61 1 1 1.5750000000000000e+00 7.7760430938164511e+00 7.4762112686089210e+00 -3.7661045029810936e-03 0 0 0 -62 1 2 2.1000000000000001e+00 6.9872221277103073e+00 1.0236400622085640e-01 -2.7608956869542940e+00 0 0 0 -63 1 2 2.1000000000000001e+00 6.9639024613826237e+00 6.1132078591126024e+00 -2.7688180306859120e+00 0 0 0 -64 1 3 -1.0500000000000000e+00 7.1847299693423636e+00 8.9971189235017555e+00 -1.1427954761034602e+00 0 0 0 -65 1 3 -1.0500000000000000e+00 6.8290445485187838e+00 6.2060511003421475e+00 -1.1440201411436348e+00 0 0 0 -66 1 4 -9.4999999999999996e-01 -1.1170179401349104e+01 7.4025715318519616e+00 -1.0139079045151256e+00 1 0 0 -67 1 3 -1.0500000000000000e+00 -9.8208722096162422e+00 5.4102617645258597e+00 -3.2426169389587720e+00 1 0 0 -68 1 3 -1.0500000000000000e+00 7.0763533880459448e+00 7.5875269446494933e+00 -3.2448428093510815e+00 0 0 0 -69 1 3 -1.0500000000000000e+00 8.2294134599018207e+00 5.2613928775960481e+00 -3.0528635113467359e+00 0 0 0 -70 1 5 4.2499999999999999e-01 -1.0663356752324118e+01 8.2814647238737038e+00 -1.1574570360611904e+00 1 0 0 -71 1 1 1.5750000000000000e+00 5.1678595511383953e+00 2.9932794956743400e+00 -3.7682495154793827e-03 0 0 0 -72 1 2 2.1000000000000001e+00 -1.1044578735544359e+01 4.5852804510839995e+00 -2.7609085188696003e+00 1 0 0 -73 1 2 2.1000000000000001e+00 -1.1124280120471164e+01 1.6303130160621073e+00 -2.7688050243051654e+00 1 0 0 -74 1 3 -1.0500000000000000e+00 -1.0903430837138755e+01 4.5142265182170114e+00 -1.1428067019922281e+00 1 0 0 -75 1 3 -1.0500000000000000e+00 -1.1259146460802429e+01 1.7231701588295429e+00 -1.1440089039848367e+00 1 0 0 -76 1 4 -9.4999999999999996e-01 6.8616453016252521e+00 2.9196822038068042e+00 -1.0139216128372404e+00 0 0 0 -77 1 3 -1.0500000000000000e+00 8.2109571487609827e+00 9.2737859539361978e-01 -3.2426323082758728e+00 0 0 0 -78 1 3 -1.0500000000000000e+00 -1.1011811761974229e+01 3.1045930104483759e+00 -3.2448303264821794e+00 1 0 0 -79 1 3 -1.0500000000000000e+00 -9.8587920774733693e+00 7.7846554865378792e-01 -3.0528473884375895e+00 1 0 0 -80 1 5 4.2499999999999999e-01 7.3684626875205588e+00 3.7985101846869256e+00 -1.1575103660650452e+00 0 0 0 -81 1 1 1.5750000000000000e+00 -7.7199281726379851e+00 1.4894790776152078e+00 -3.2724555993777216e-03 1 0 0 -82 1 2 2.1000000000000001e+00 -6.9311483564799579e+00 8.8633038807281785e+00 2.7538960009466376e+00 1 0 0 -83 1 2 2.1000000000000001e+00 -6.9077956621698489e+00 2.8524895765317808e+00 2.7617665991751519e+00 1 0 0 -84 1 3 -1.0500000000000000e+00 -7.1284775002355394e+00 -3.1324481964453810e-02 1.1357365527598446e+00 1 0 0 -85 1 3 -1.0500000000000000e+00 -6.7729673531069245e+00 2.7594471850213687e+00 1.1370450097681122e+00 1 0 0 -86 1 4 -9.4999999999999996e-01 -9.4136030086299414e+00 1.5632161786690695e+00 1.0068890206431487e+00 1 0 0 -87 1 3 -1.0500000000000000e+00 -1.0763007134831607e+01 3.5553762279049508e+00 3.2357432836676043e+00 1 0 0 -88 1 3 -1.0500000000000000e+00 -7.0200779492618830e+00 1.3781321729757572e+00 3.2376887121993452e+00 1 0 0 -89 1 3 -1.0500000000000000e+00 -8.1733196741368719e+00 3.7042082476166307e+00 3.0458512074393269e+00 1 0 0 -90 1 5 4.2499999999999999e-01 -9.9205252798252292e+00 6.8417198273265356e-01 1.1506460579325335e+00 1 0 0 -91 1 1 1.5750000000000000e+00 -5.1117549333116692e+00 5.9724138904908486e+00 -3.2727103645768807e-03 1 0 0 -92 1 2 2.1000000000000001e+00 -9.5393407151183922e+00 4.3803927214282616e+00 2.7538964523725067e+00 1 0 0 -93 1 2 2.1000000000000001e+00 -9.4596208013141094e+00 7.3353758537792650e+00 2.7617621570838597e+00 1 0 0 -94 1 3 -1.0500000000000000e+00 -9.6803336059686469e+00 4.4515688238064364e+00 1.1357629650983831e+00 1 0 0 -95 1 3 -1.0500000000000000e+00 -9.3247719839755963e+00 7.2423306831909962e+00 1.1370278292451879e+00 1 0 0 -96 1 4 -9.4999999999999996e-01 -6.8054254594612225e+00 6.0461058148285396e+00 1.0068978172920957e+00 1 0 0 -97 1 3 -1.0500000000000000e+00 -8.1548120968869000e+00 8.0382775480633875e+00 3.2357637642174133e+00 1 0 0 -98 1 3 -1.0500000000000000e+00 -9.5719143673187084e+00 5.8610700576774661e+00 3.2376852155298828e+00 1 0 0 -99 1 3 -1.0500000000000000e+00 -1.0725132281094336e+01 8.1871457107003032e+00 3.0458339522302751e+00 1 0 0 -100 1 5 4.2499999999999999e-01 -7.3123591493045659e+00 5.1671352420150960e+00 1.1506725160907028e+00 1 0 0 -101 1 1 1.5750000000000000e+00 -7.7039661392078020e+00 7.4762121719255390e+00 -3.7682078301308763e-03 1 0 0 -102 1 2 2.1000000000000001e+00 -8.4927550473127180e+00 1.0235486645645508e-01 -2.7608951403105042e+00 1 0 0 -103 1 2 2.1000000000000001e+00 -8.5160852926969905e+00 6.1131990991198997e+00 -2.7688142320374940e+00 1 0 0 -104 1 3 -1.0500000000000000e+00 -8.2952641286984203e+00 8.9971169044920778e+00 -1.1428134840038755e+00 1 0 0 -105 1 3 -1.0500000000000000e+00 -8.6509603566434361e+00 6.2060607665068055e+00 -1.1440124271361789e+00 1 0 0 -106 1 4 -9.4999999999999996e-01 -6.0101827955527565e+00 7.4025603031072329e+00 -1.0139213710091308e+00 1 0 0 -107 1 3 -1.0500000000000000e+00 -4.6608455934220148e+00 5.4102827452969429e+00 -3.2426107408542437e+00 1 0 0 -108 1 3 -1.0500000000000000e+00 -8.4036457935644169e+00 7.5875425899482565e+00 -3.2448384441709388e+00 1 0 0 -109 1 3 -1.0500000000000000e+00 -7.2505982941478297e+00 5.2613968699746003e+00 -3.0528607675410457e+00 1 0 0 -110 1 5 4.2499999999999999e-01 -5.5033762395629582e+00 8.2814550493740740e+00 -1.1575499564338703e+00 1 0 0 -111 1 1 1.5750000000000000e+00 -1.0312127848754963e+01 2.9932710802095919e+00 -3.7629014077342759e-03 1 0 0 -112 1 2 2.1000000000000001e+00 -5.8845878185650982e+00 4.5852698968409165e+00 -2.7608938634931910e+00 1 0 0 -113 1 2 2.1000000000000001e+00 -5.9642725250308875e+00 1.6303233843688680e+00 -2.7688124598580766e+00 1 0 0 -114 1 3 -1.0500000000000000e+00 -5.7434150738103007e+00 4.5142286422205764e+00 -1.1428184018271512e+00 1 0 0 -115 1 3 -1.0500000000000000e+00 -6.0991511904217299e+00 1.7231673138735495e+00 -1.1440030942049173e+00 1 0 0 -116 1 4 -9.4999999999999996e-01 -8.6183814565733705e+00 2.9196490081391033e+00 -1.0139414870485535e+00 1 0 0 -117 1 3 -1.0500000000000000e+00 -7.2690682215044822e+00 9.2736362008184159e-01 -3.2426264066786432e+00 1 0 0 -118 1 3 -1.0500000000000000e+00 -5.8518082502983955e+00 3.1045928031364411e+00 -3.2448477388756478e+00 1 0 0 -119 1 3 -1.0500000000000000e+00 -4.6987742978898988e+00 7.7845301166729186e-01 -3.0528450718806761e+00 1 0 0 -120 1 5 4.2499999999999999e-01 -8.1115594830260207e+00 3.7984876081206806e+00 -1.1576664325795285e+00 1 0 0 -121 1 1 1.5750000000000000e+00 -2.5599150854889094e+00 1.4894706170264342e+00 -3.2674360429911786e-03 1 0 0 -122 1 2 2.1000000000000001e+00 -1.7711425777258931e+00 8.8633146161589806e+00 2.7538807796770186e+00 1 0 0 -123 1 2 2.1000000000000001e+00 -1.7478054130511396e+00 2.8524797344303252e+00 2.7617739588054651e+00 1 0 0 -124 1 3 -1.0500000000000000e+00 -1.9684931255098146e+00 -3.1325651116073772e-02 1.1357490996153903e+00 1 0 0 -125 1 3 -1.0500000000000000e+00 -1.6129621986767120e+00 2.7594493305451913e+00 1.1370386304640405e+00 1 0 0 -126 1 4 -9.4999999999999996e-01 -4.2536299560830892e+00 1.5631828595113966e+00 1.0068699983288631e+00 1 0 0 -127 1 3 -1.0500000000000000e+00 -5.6030339285886290e+00 3.5553594737746543e+00 3.2357491377820011e+00 1 0 0 -128 1 3 -1.0500000000000000e+00 -1.8600810558661927e+00 1.3781316682245190e+00 3.2377051692239878e+00 1 0 0 -129 1 3 -1.0500000000000000e+00 -3.0133359720352626e+00 3.7042198037561391e+00 3.0458483427178091e+00 1 0 0 -130 1 5 4.2499999999999999e-01 -4.7605464608785963e+00 6.8414990826685695e-01 1.1504933665649624e+00 1 0 0 -131 1 1 1.5750000000000000e+00 4.8252971132846767e-02 5.9724140153684573e+00 -3.2715658741668818e-03 1 0 0 -132 1 2 2.1000000000000001e+00 -4.3793184632079472e+00 4.3803847290240121e+00 2.7538960659004399e+00 1 0 0 -133 1 2 2.1000000000000001e+00 -4.2996100770438455e+00 7.3353642603157603e+00 2.7617667119934151e+00 1 0 0 -134 1 3 -1.0500000000000000e+00 -4.5203291270400356e+00 4.4515663398601113e+00 1.1357454518209789e+00 1 0 0 -135 1 3 -1.0500000000000000e+00 -4.1647764890169432e+00 7.2423401299927299e+00 1.1370344961840431e+00 1 0 0 -136 1 4 -9.4999999999999996e-01 -1.6454185074090386e+00 6.0461211420920371e+00 1.0069142678365317e+00 1 0 0 -137 1 3 -1.0500000000000000e+00 -2.9948349753606820e+00 8.0382595250699929e+00 3.2357578355633851e+00 1 0 0 -138 1 3 -1.0500000000000000e+00 -4.4119132227444346e+00 5.8610867870033019e+00 3.2376918486063424e+00 1 0 0 -139 1 3 -1.0500000000000000e+00 -5.5651452482014427e+00 8.1871507623420428e+00 3.0458360372166311e+00 1 0 0 -140 1 5 4.2499999999999999e-01 -2.1523364466372712e+00 5.1671496373027175e+00 1.1507886916566683e+00 1 0 0 -141 1 1 1.5750000000000000e+00 -2.5439566444245010e+00 7.4762112209052383e+00 -3.7662775479017085e-03 1 0 0 -142 1 2 2.1000000000000001e+00 -3.3327770319686962e+00 1.0236445803406014e-01 -2.7608954657080140e+00 1 0 0 -143 1 2 2.1000000000000001e+00 -3.3560968225599401e+00 6.1132081297483190e+00 -2.7688181718580109e+00 1 0 0 -144 1 3 -1.0500000000000000e+00 -3.1352704458339078e+00 8.9971190839726631e+00 -1.1427951007065573e+00 1 0 0 -145 1 3 -1.0500000000000000e+00 -3.4909559457041324e+00 6.2060507675043333e+00 -1.1440204115643127e+00 1 0 0 -146 1 4 -9.4999999999999996e-01 -8.5017933782899036e-01 7.4025711769369202e+00 -1.0139080031312293e+00 1 0 0 -147 1 3 -1.0500000000000000e+00 4.9912708373973835e-01 5.4102616063578708e+00 -3.2426169490766288e+00 1 0 0 -148 1 3 -1.0500000000000000e+00 -3.2436472194278476e+00 7.5875263788260945e+00 -3.2448433115530761e+00 1 0 0 -149 1 3 -1.0500000000000000e+00 -2.0905863460581759e+00 5.2613927792139954e+00 -3.0528639226122767e+00 1 0 0 -150 1 5 4.2499999999999999e-01 -3.4335653949917244e-01 8.2814649799908011e+00 -1.1574574055638855e+00 1 0 0 -151 1 1 1.5750000000000000e+00 -5.1521404274402407e+00 2.9932795557898082e+00 -3.7680306824974252e-03 1 0 0 -152 1 2 2.1000000000000001e+00 -7.2457871207509861e-01 4.5852797211023919e+00 -2.7609088010670852e+00 1 0 0 -153 1 2 2.1000000000000001e+00 -8.0428086665862075e-01 1.6303133125527722e+00 -2.7688049343933923e+00 1 0 0 -154 1 3 -1.0500000000000000e+00 -5.8343093933598666e-01 4.5142267968591376e+00 -1.1428066085208357e+00 1 0 0 -155 1 3 -1.0500000000000000e+00 -9.3914622858366670e-01 1.7231700956648055e+00 -1.1440088196464711e+00 1 0 0 -156 1 4 -9.4999999999999996e-01 -3.4583543601678235e+00 2.9196834237039830e+00 -1.0139212715896715e+00 1 0 0 -157 1 3 -1.0500000000000000e+00 -2.1090423826736071e+00 9.2737904555706407e-01 -3.2426328776455264e+00 1 0 0 -158 1 3 -1.0500000000000000e+00 -6.9181166114669601e-01 3.1045939749993074e+00 -3.2448305477291193e+00 1 0 0 -159 1 3 -1.0500000000000000e+00 4.6120793659927273e-01 7.7846512670406298e-01 -3.0528475173831282e+00 1 0 0 -160 1 5 4.2499999999999999e-01 -2.9515369386160293e+00 3.7985107923601902e+00 -1.1575067719378200e+00 1 0 0 -161 1 1 1.5750000000000000e+00 2.6563989185621697e+00 1.0455321895488769e+01 -3.2762588329369180e-03 0 0 0 -162 1 2 2.1000000000000001e+00 3.2198338942299962e+00 -1.8034180438769312e+01 2.7539045325154952e+00 0 1 0 -163 1 2 2.1000000000000001e+00 3.4685420976023327e+00 1.1818309915154089e+01 2.7617701798617826e+00 0 0 0 -164 1 3 -1.0500000000000000e+00 3.2478451452900838e+00 8.9345035359001521e+00 1.1357517024424695e+00 0 0 0 -165 1 3 -1.0500000000000000e+00 3.6033716610399829e+00 1.1725263629349289e+01 1.1370436349851865e+00 0 0 0 -166 1 4 -9.4999999999999996e-01 9.6276915931304607e-01 1.0529096885950434e+01 1.0069347805155928e+00 0 0 0 -167 1 3 -1.0500000000000000e+00 -3.8666356265307122e-01 1.2521194387407096e+01 3.2357442840378923e+00 0 0 0 -168 1 3 -1.0500000000000000e+00 3.3562645144848258e+00 1.0343984632188544e+01 3.2376585390762695e+00 0 0 0 -169 1 3 -1.0500000000000000e+00 2.2030139553919152e+00 1.2670029659309332e+01 3.0458538764694207e+00 0 0 0 -170 1 5 4.2499999999999999e-01 4.5583534879090593e-01 9.6500966233062790e+00 1.1509976244895963e+00 0 0 0 -171 1 1 1.5750000000000000e+00 5.2645804008917914e+00 1.4938212777711680e+01 -3.2699391108348408e-03 0 0 0 -172 1 2 2.1000000000000001e+00 8.3700178762454414e-01 1.3346240941494244e+01 2.7538856869733728e+00 0 0 0 -173 1 2 2.1000000000000001e+00 9.1670173505335306e-01 1.6301214338866860e+01 2.7617644421088432e+00 0 0 0 -174 1 3 -1.0500000000000000e+00 6.9601370418275010e-01 1.3417400877129523e+01 1.1357494354954341e+00 0 0 0 -175 1 3 -1.0500000000000000e+00 1.0515475883742784e+00 1.6208170709964772e+01 1.1370347918279791e+00 0 0 0 -176 1 4 -9.4999999999999996e-01 3.5708778167504427e+00 1.5011903925901866e+01 1.0068638471664286e+00 0 0 0 -177 1 3 -1.0500000000000000e+00 2.2215014317380977e+00 1.7004108589789258e+01 3.2357547344228585e+00 0 0 0 -178 1 3 -1.0500000000000000e+00 8.0441865697185477e-01 1.4826861212618862e+01 3.2377028072007512e+00 0 0 0 -179 1 3 -1.0500000000000000e+00 -3.4880995646462942e-01 1.7152956450342980e+01 3.0458414005831536e+00 0 0 0 -180 1 5 4.2499999999999999e-01 3.0639529840814195e+00 1.4132875829311541e+01 1.1504351342271377e+00 0 0 0 -181 1 1 1.5750000000000000e+00 2.6723615194140677e+00 1.6442023399895145e+01 -3.7682517850203823e-03 0 0 0 -182 1 2 2.1000000000000001e+00 1.8835787239124393e+00 9.0681552640911072e+00 -2.7608879508938262e+00 0 0 0 -183 1 2 2.1000000000000001e+00 1.8602366759051847e+00 1.5079041458825895e+01 -2.7688068742259579e+00 0 0 0 -184 1 3 -1.0500000000000000e+00 1.8557359902853232e+00 -1.7900333969854724e+01 -1.1428135029016779e+00 0 1 0 -185 1 3 -1.0500000000000000e+00 1.7253575492439523e+00 1.5171900079888406e+01 -1.1440049164116175e+00 0 0 0 -186 1 4 -9.4999999999999996e-01 4.3661514573287654e+00 1.6368415136999023e+01 -1.0139166296354674e+00 0 0 0 -187 1 3 -1.0500000000000000e+00 5.7154690322009074e+00 1.4376111304605590e+01 -3.2426223925272826e+00 0 0 0 -188 1 3 -1.0500000000000000e+00 1.9726946608641462e+00 1.6553353247753808e+01 -3.2448482730141261e+00 0 0 0 -189 1 3 -1.0500000000000000e+00 3.1257184502843245e+00 1.4227200410253584e+01 -3.0528478566956565e+00 0 0 0 -190 1 5 4.2499999999999999e-01 4.8729566638827162e+00 1.7247278927055046e+01 -1.1574780666926721e+00 0 0 0 -191 1 1 1.5750000000000000e+00 6.4216158852561378e-02 1.1959087051646971e+01 -3.7600341225090261e-03 0 0 0 -192 1 2 2.1000000000000001e+00 4.4917376476188586e+00 1.3551099659023443e+01 -2.7608932003969073e+00 0 0 0 -193 1 2 2.1000000000000001e+00 4.4120660877589497e+00 1.0596136461956402e+01 -2.7688197432703880e+00 0 0 0 -194 1 3 -1.0500000000000000e+00 4.6329255251992549e+00 1.3480037101567749e+01 -1.1428288328770435e+00 0 0 0 -195 1 3 -1.0500000000000000e+00 4.2771911872604029e+00 1.0688984410239879e+01 -1.1440062182642876e+00 0 0 0 -196 1 4 -9.4999999999999996e-01 1.7579262759916023e+00 1.1885411942310235e+01 -1.0139768699759095e+00 0 0 0 -197 1 3 -1.0500000000000000e+00 3.1072726976913465e+00 9.8931866067750391e+00 -3.2426197851717671e+00 0 0 0 -198 1 3 -1.0500000000000000e+00 4.5245182257238810e+00 1.2070401768702606e+01 -3.2448203553152579e+00 0 0 0 -199 1 3 -1.0500000000000000e+00 5.6775707113324163e+00 9.7442894482667093e+00 -3.0528548068449783e+00 0 0 0 -200 1 5 4.2499999999999999e-01 2.2647577755846964e+00 1.2764238323389506e+01 -1.1579590097052694e+00 0 0 0 -201 1 1 1.5750000000000000e+00 7.8164117287632848e+00 1.0455313418416040e+01 -3.2710202176904346e-03 0 0 0 -202 1 2 2.1000000000000001e+00 -1.2260159433678718e+01 -1.8034169647358517e+01 2.7538897492176346e+00 1 1 0 -203 1 2 2.1000000000000001e+00 -1.2011466253318112e+01 1.1818300832633188e+01 2.7617775417844861e+00 1 0 0 -204 1 3 -1.0500000000000000e+00 8.4078297514478351e+00 8.9345021777364160e+00 1.1357646883988455e+00 0 0 0 -205 1 3 -1.0500000000000000e+00 -1.1876624030225933e+01 1.1725266199229221e+01 1.1370373498931343e+00 1 0 0 -206 1 4 -9.4999999999999996e-01 6.1227442368102558e+00 1.0529066727945761e+01 1.0069175335604896e+00 0 0 0 -207 1 3 -1.0500000000000000e+00 4.7733106561845826e+00 1.2521178410831844e+01 3.2357495358217694e+00 0 0 0 -208 1 3 -1.0500000000000000e+00 -1.2123739199923346e+01 1.0343983924515531e+01 3.2376750805178460e+00 1 0 0 -209 1 3 -1.0500000000000000e+00 7.3629980319339339e+00 1.2670040945865967e+01 3.0458509877817406e+00 0 0 0 -210 1 5 4.2499999999999999e-01 5.6158158152958784e+00 9.6500772916969204e+00 1.1508595237001344e+00 0 0 0 -211 1 1 1.5750000000000000e+00 -1.0215411238357737e+01 1.4938212754513795e+01 -3.2687505359643154e-03 1 0 0 -212 1 2 2.1000000000000001e+00 5.9970233475307388e+00 1.3346232178649366e+01 2.7538855730068423e+00 0 0 0 -213 1 2 2.1000000000000001e+00 6.0767126747095546e+00 1.6301204585436718e+01 2.7617687594200788e+00 0 0 0 -214 1 3 -1.0500000000000000e+00 5.8560186155367475e+00 1.3417398798963887e+01 1.1357327828274588e+00 0 0 0 -215 1 3 -1.0500000000000000e+00 6.2115434941113854e+00 1.6208179920458090e+01 1.1370418249592653e+00 0 0 0 -216 1 4 -9.4999999999999996e-01 -1.1909115839139879e+01 1.5011918778012269e+01 1.0068791242057937e+00 1 0 0 -217 1 3 -1.0500000000000000e+00 7.3814787112119937e+00 1.7004090310444280e+01 3.2357485436885103e+00 0 0 0 -218 1 3 -1.0500000000000000e+00 5.9644198302019831e+00 1.4826876996357161e+01 3.2377087426592492e+00 0 0 0 -219 1 3 -1.0500000000000000e+00 4.8111764532162535e+00 1.7152961397442720e+01 3.0458439196033620e+00 0 0 0 -220 1 5 4.2499999999999999e-01 8.2239745440285787e+00 1.4132887903922470e+01 1.1505437168075829e+00 0 0 0 -221 1 1 1.5750000000000000e+00 7.8323706771304558e+00 1.6442022820550246e+01 -3.7665242395927834e-03 0 0 0 -222 1 2 2.1000000000000001e+00 7.0435574833984198e+00 9.0681651728979631e+00 -2.7608886881351333e+00 0 0 0 -223 1 2 2.1000000000000001e+00 7.0202249181798919e+00 1.5079050811449275e+01 -2.7688110905744079e+00 0 0 0 -224 1 3 -1.0500000000000000e+00 7.0157303511476421e+00 -1.7900331966671079e+01 -1.1427956373922825e+00 0 1 0 -225 1 3 -1.0500000000000000e+00 6.8853621549262058e+00 1.5171890452553551e+01 -1.1440125090426640e+00 0 0 0 -226 1 4 -9.4999999999999996e-01 -1.1113844930760134e+01 1.6368426269497132e+01 -1.0139030599392669e+00 1 0 0 -227 1 3 -1.0500000000000000e+00 -9.7645556324506551e+00 1.4376091960320959e+01 -3.2426286772008348e+00 1 0 0 -228 1 3 -1.0500000000000000e+00 7.1326934249216940e+00 1.6553337457108437e+01 -3.2448533925876024e+00 0 0 0 -229 1 3 -1.0500000000000000e+00 8.2857297888025840e+00 1.4227196090097426e+01 -3.0528499396628153e+00 0 0 0 -230 1 5 4.2499999999999999e-01 -1.0607023231214001e+01 1.7247289041351092e+01 -1.1573840935904762e+00 1 0 0 -231 1 1 1.5750000000000000e+00 5.2242038308482766e+00 1.1959095287538190e+01 -3.7653283250147496e-03 0 0 0 -232 1 2 2.1000000000000001e+00 -1.0988253694542321e+01 1.3551109824974606e+01 -2.7609081895324890e+00 1 0 0 -233 1 2 2.1000000000000001e+00 -1.1067941150601820e+01 1.0596125949081394e+01 -2.7688120214376628e+00 1 0 0 -234 1 3 -1.0500000000000000e+00 -1.0847089918133126e+01 1.3480035044199898e+01 -1.1428177120780383e+00 1 0 0 -235 1 3 -1.0500000000000000e+00 -1.1202804668208714e+01 1.0688988083255079e+01 -1.1440123111676286e+00 1 0 0 -236 1 4 -9.4999999999999996e-01 6.9179518926221384e+00 1.1885443786471409e+01 -1.0139581045576271e+00 0 0 0 -237 1 3 -1.0500000000000000e+00 8.2672954375049912e+00 9.8932003039765952e+00 -3.2426259216543594e+00 0 0 0 -238 1 3 -1.0500000000000000e+00 -1.0955485470410157e+01 1.2070403361540542e+01 -3.2448030648081110e+00 1 0 0 -239 1 3 -1.0500000000000000e+00 -9.8024465472705913e+00 9.7443011929395063e+00 -3.0528568566460059e+00 1 0 0 -240 1 5 4.2499999999999999e-01 7.4247786536253990e+00 1.2764258784769812e+01 -1.1578112291313278e+00 0 0 0 -241 1 1 1.5750000000000000e+00 -7.6636008658381130e+00 1.0455321835738001e+01 -3.2764761174721713e-03 1 0 0 -242 1 2 2.1000000000000001e+00 -7.1001654469134188e+00 -1.8034180376500476e+01 2.7539046011956927e+00 1 1 0 -243 1 2 2.1000000000000001e+00 -6.8514574784571227e+00 1.1818310242478901e+01 2.7617701816715385e+00 1 0 0 -244 1 3 -1.0500000000000000e+00 -7.0721551451225491e+00 8.9345037013666655e+00 1.1357518502984245e+00 1 0 0 -245 1 3 -1.0500000000000000e+00 -6.7166288540019190e+00 1.1725263569422886e+01 1.1370434222933952e+00 1 0 0 -246 1 4 -9.4999999999999996e-01 -9.3572304445276497e+00 1.0529097191669276e+01 1.0069347850610182e+00 1 0 0 -247 1 3 -1.0500000000000000e+00 -1.0706664101499596e+01 1.2521194361088551e+01 3.2357439254670783e+00 1 0 0 -248 1 3 -1.0500000000000000e+00 -6.9637360287682002e+00 1.0343984238065591e+01 3.2376581390482588e+00 1 0 0 -249 1 3 -1.0500000000000000e+00 -8.1169857028361836e+00 1.2670029287478943e+01 3.0458536357709072e+00 1 0 0 -250 1 5 4.2499999999999999e-01 -9.8641646031541530e+00 9.6500965949313660e+00 1.1509981946332442e+00 1 0 0 -251 1 1 1.5750000000000000e+00 -5.0554195176290548e+00 1.4938212967058394e+01 -3.2697777500576564e-03 1 0 0 -252 1 2 2.1000000000000001e+00 -9.4829984656337594e+00 1.3346240650458814e+01 2.7538856400619860e+00 1 0 0 -253 1 2 2.1000000000000001e+00 -9.4032984378370177e+00 1.6301214599327221e+01 2.7617642997979068e+00 1 0 0 -254 1 3 -1.0500000000000000e+00 -9.6239862728068335e+00 1.3417400991384010e+01 1.1357495594830080e+00 1 0 0 -255 1 3 -1.0500000000000000e+00 -9.2684523756676356e+00 1.6208170487547630e+01 1.1370348465046902e+00 1 0 0 -256 1 4 -9.4999999999999996e-01 -6.7491223170950736e+00 1.5011904066194635e+01 1.0068636794011177e+00 1 0 0 -257 1 3 -1.0500000000000000e+00 -8.0984979601998077e+00 1.7004109138008342e+01 3.2357545474688134e+00 1 0 0 -258 1 3 -1.0500000000000000e+00 -9.5155814568970030e+00 1.4826861602240196e+01 3.2377025933365946e+00 1 0 0 -259 1 3 -1.0500000000000000e+00 -1.0668810401502405e+01 1.7152956142283916e+01 3.0458415506199348e+00 1 0 0 -260 1 5 4.2499999999999999e-01 -7.2560469500703286e+00 1.4132875650393093e+01 1.1504350015414087e+00 1 0 0 -261 1 1 1.5750000000000000e+00 -7.6476382605535251e+00 1.6442023572464432e+01 -3.7685047931237392e-03 1 0 0 -262 1 2 2.1000000000000001e+00 -8.4364212215203960e+00 9.0681553218020703e+00 -2.7608877807018164e+00 1 0 0 -263 1 2 2.1000000000000001e+00 -8.4597634672522837e+00 1.5079041833261041e+01 -2.7688070745421216e+00 1 0 0 -264 1 3 -1.0500000000000000e+00 -8.4642639727977436e+00 -1.7900333542265852e+01 -1.1428133923223545e+00 1 1 0 -265 1 3 -1.0500000000000000e+00 -8.5946426769864424e+00 1.5171899606907981e+01 -1.1440046137962465e+00 1 0 0 -266 1 4 -9.4999999999999996e-01 -5.9538485120758615e+00 1.6368414843436707e+01 -1.0139169448439258e+00 1 0 0 -267 1 3 -1.0500000000000000e+00 -4.6045307535975972e+00 1.4376111355998557e+01 -3.2426221919976284e+00 1 0 0 -268 1 3 -1.0500000000000000e+00 -8.3473055037395962e+00 1.6553353037744937e+01 -3.2448489745001829e+00 1 0 0 -269 1 3 -1.0500000000000000e+00 -7.1942820610090816e+00 1.4227200247521328e+01 -3.0528477760774004e+00 1 0 0 -270 1 5 4.2499999999999999e-01 -5.4470436023502824e+00 1.7247278596321525e+01 -1.1574797469732854e+00 1 0 0 -271 1 1 1.5750000000000000e+00 -1.0255783910077239e+01 1.1959086991585444e+01 -3.7600807372335510e-03 1 0 0 -272 1 2 2.1000000000000001e+00 -5.8282621980854525e+00 1.3551099962667056e+01 -2.7608931703077699e+00 1 0 0 -273 1 2 2.1000000000000001e+00 -5.9079338844753870e+00 1.0596135943862595e+01 -2.7688196418920841e+00 1 0 0 -274 1 3 -1.0500000000000000e+00 -5.6870744047512298e+00 1.3480036754658695e+01 -1.1428296840253562e+00 1 0 0 -275 1 3 -1.0500000000000000e+00 -6.0428089895535866e+00 1.0688984768387638e+01 -1.1440066122506938e+00 1 0 0 -276 1 4 -9.4999999999999996e-01 -8.5620738246968404e+00 1.1885411722233716e+01 -1.0139770124730223e+00 1 0 0 -277 1 3 -1.0500000000000000e+00 -7.2127277610459872e+00 9.8931866337596439e+00 -3.2426199012467078e+00 1 0 0 -278 1 3 -1.0500000000000000e+00 -5.7954818935627088e+00 1.2070402327865740e+01 -3.2448199815493428e+00 1 0 0 -279 1 3 -1.0500000000000000e+00 -4.6424288385626173e+00 9.7442891001361325e+00 -3.0528547464974949e+00 1 0 0 -280 1 5 4.2499999999999999e-01 -8.0552423316030755e+00 1.2764238338648244e+01 -1.1579596574304247e+00 1 0 0 -281 1 1 1.5750000000000000e+00 -2.5035881332540626e+00 1.0455313438281006e+01 -3.2712044999829715e-03 1 0 0 -282 1 2 2.1000000000000001e+00 -1.9401593817067511e+00 -1.8034169707411234e+01 2.7538898161357235e+00 1 1 0 -283 1 2 2.1000000000000001e+00 -1.6914664486640572e+00 1.1818301093805825e+01 2.7617776942859695e+00 1 0 0 -284 1 3 -1.0500000000000000e+00 -1.9121703478062582e+00 8.9345026830907521e+00 1.1357649571227402e+00 1 0 0 -285 1 3 -1.0500000000000000e+00 -1.5566243100046933e+00 1.1725265969565267e+01 1.1370373202513679e+00 1 0 0 -286 1 4 -9.4999999999999996e-01 -4.1972557876600138e+00 1.0529066424023107e+01 1.0069172680296870e+00 1 0 0 -287 1 3 -1.0500000000000000e+00 -5.5466887598591352e+00 1.2521178836475631e+01 3.2357497502625563e+00 1 0 0 -288 1 3 -1.0500000000000000e+00 -1.8037393560046233e+00 1.0343983628590454e+01 3.2376745681969599e+00 1 0 0 -289 1 3 -1.0500000000000000e+00 -2.9570022454137304e+00 1.2670040534923213e+01 3.0458509306017678e+00 1 0 0 -290 1 5 4.2499999999999999e-01 -4.7041844502273866e+00 9.6500770541189276e+00 1.1508579675649457e+00 1 0 0 -291 1 1 1.5750000000000000e+00 1.0458876014466689e-01 1.4938212644875197e+01 -3.2686548536950966e-03 1 0 0 -292 1 2 2.1000000000000001e+00 -4.3229766381232686e+00 1.3346232668830169e+01 2.7538857767413205e+00 1 0 0 -293 1 2 2.1000000000000001e+00 -4.2432874159283642e+00 1.6301204147800600e+01 2.7617687132492854e+00 1 0 0 -294 1 3 -1.0500000000000000e+00 -4.4639811909059190e+00 1.3417398404608658e+01 1.1357321894355046e+00 1 0 0 -295 1 3 -1.0500000000000000e+00 -4.1084567350115320e+00 1.6208180182308443e+01 1.1370413362795944e+00 1 0 0 -296 1 4 -9.4999999999999996e-01 -1.5891161884471394e+00 1.5011918082162470e+01 1.0068788955723686e+00 1 0 0 -297 1 3 -1.0500000000000000e+00 -2.9385222256091570e+00 1.7004090175732845e+01 3.2357489633106518e+00 1 0 0 -298 1 3 -1.0500000000000000e+00 -4.3555803148242056e+00 1.4826877518512493e+01 3.2377090569543814e+00 1 0 0 -299 1 3 -1.0500000000000000e+00 -5.5088230300342360e+00 1.7152961020804806e+01 3.0458441266118772e+00 1 0 0 -300 1 5 4.2499999999999999e-01 -2.0960255345568868e+00 1.4132887966264132e+01 1.1505421012955246e+00 1 0 0 -301 1 1 1.5750000000000000e+00 -2.4876293318656488e+00 1.6442022763627239e+01 -3.7666356009875557e-03 1 0 0 -302 1 2 2.1000000000000001e+00 -3.2764421637592598e+00 9.0681653305981094e+00 -2.7608885696105663e+00 1 0 0 -303 1 2 2.1000000000000001e+00 -3.2997743536479165e+00 1.5079051409736575e+01 -2.7688110927527605e+00 1 0 0 -304 1 3 -1.0500000000000000e+00 -3.3042698108183330e+00 -1.7900331712839787e+01 -1.1427954583030111e+00 1 1 0 -305 1 3 -1.0500000000000000e+00 -3.4346383314865108e+00 1.5171890214740376e+01 -1.1440125299463340e+00 1 0 0 -306 1 4 -9.4999999999999996e-01 -7.9384436021782179e-01 1.6368426821249084e+01 -1.0139027798280118e+00 1 0 0 -307 1 3 -1.0500000000000000e+00 5.5544386481953012e-01 1.4376091897769367e+01 -3.2426289640000885e+00 1 0 0 -308 1 3 -1.0500000000000000e+00 -3.1873069572855641e+00 1.6553337313720473e+01 -3.2448539136716885e+00 1 0 0 -309 1 3 -1.0500000000000000e+00 -2.0342700588836031e+00 1.4227195912115622e+01 -3.0528501058090836e+00 1 0 0 -310 1 5 4.2499999999999999e-01 -2.8702298571735341e-01 1.7247289483682533e+01 -1.1573818576236032e+00 1 0 0 -311 1 1 1.5750000000000000e+00 -5.0957961243148961e+00 1.1959095378088897e+01 -3.7652310565796654e-03 1 0 0 -312 1 2 2.1000000000000001e+00 -6.6825401333147383e-01 1.3551109613358943e+01 -2.7609081732083842e+00 1 0 0 -313 1 2 2.1000000000000001e+00 -7.4794174296430427e-01 1.0596126561677334e+01 -2.7688120279726816e+00 1 0 0 -314 1 3 -1.0500000000000000e+00 -5.2708988437583137e-01 1.3480035130746888e+01 -1.1428176328983515e+00 1 0 0 -315 1 3 -1.0500000000000000e+00 -8.8280456031347754e-01 1.0688988054446025e+01 -1.1440122210630470e+00 1 0 0 -316 1 4 -9.4999999999999996e-01 -3.4020481602257746e+00 1.1885443987601221e+01 -1.0139581992187718e+00 1 0 0 -317 1 3 -1.0500000000000000e+00 -2.0527042783937013e+00 9.8932006651577318e+00 -3.2426261205128348e+00 1 0 0 -318 1 3 -1.0500000000000000e+00 -6.3548545018103475e-01 1.2070403327318452e+01 -3.2448029842827628e+00 1 0 0 -319 1 3 -1.0500000000000000e+00 5.1755357781316746e-01 9.7443009393659423e+00 -3.0528568378507295e+00 1 0 0 -320 1 5 4.2499999999999999e-01 -2.8952213812924699e+00 1.2764258469873834e+01 -1.1578117683205491e+00 1 0 0 -321 1 1 1.5750000000000000e+00 2.4874010473119803e+00 -1.6442132501664730e+01 -3.2766362744336419e-03 0 1 0 -322 1 2 2.1000000000000001e+00 3.2761664028351909e+00 -9.0683383232987111e+00 2.7538984831179967e+00 0 1 0 -323 1 2 2.1000000000000001e+00 3.2995518476334684e+00 -1.5079179182315636e+01 2.7617636301428963e+00 0 1 0 -324 1 3 -1.0500000000000000e+00 3.0788351866421024e+00 -1.7962983521995717e+01 1.1357548626923020e+00 0 1 0 -325 1 3 -1.0500000000000000e+00 3.4343854310904280e+00 -1.5172222653811176e+01 1.1370349981475520e+00 0 1 0 -326 1 4 -9.4999999999999996e-01 7.9377200522738001e-01 -1.6368394316648537e+01 1.0069376355619895e+00 0 1 0 -327 1 3 -1.0500000000000000e+00 -5.5564643060713159e-01 -1.4376281678504066e+01 3.2357555064360177e+00 0 1 0 -328 1 3 -1.0500000000000000e+00 3.1872558908354840e+00 -1.6553468695914969e+01 3.2376646774315283e+00 0 1 0 -329 1 3 -1.0500000000000000e+00 2.0340286978649775e+00 -1.4227419630508681e+01 3.0458402753254532e+00 0 1 0 -330 1 5 4.2499999999999999e-01 2.8683756666122662e-01 -1.7247357291334513e+01 1.1509835662236121e+00 0 1 0 -331 1 1 1.5750000000000000e+00 5.0955669455187973e+00 -1.1959252721656203e+01 -3.2726488814915911e-03 0 1 0 -332 1 2 2.1000000000000001e+00 6.6800855681929860e-01 -1.3551231023884428e+01 2.7538837290142837e+00 0 1 0 -333 1 2 2.1000000000000001e+00 7.4769131540883116e-01 -1.0596242010541390e+01 2.7617712286800469e+00 0 1 0 -334 1 3 -1.0500000000000000e+00 5.2700540595764878e-01 -1.3480052279876823e+01 1.1357586810021552e+00 0 1 0 -335 1 3 -1.0500000000000000e+00 8.8253366419125179e-01 -1.0689290549186557e+01 1.1370392556360898e+00 0 1 0 -336 1 4 -9.4999999999999996e-01 3.4018966935470552e+00 -1.1885507734670171e+01 1.0068947610878531e+00 0 1 0 -337 1 3 -1.0500000000000000e+00 2.0524897365556107e+00 -9.8933580767891947e+00 3.2357470038009293e+00 0 1 0 -338 1 3 -1.0500000000000000e+00 6.3542254116727115e-01 -1.2070599198409424e+01 3.2376774413092200e+00 0 1 0 -339 1 3 -1.0500000000000000e+00 -5.1782743799852149e-01 -9.7445278941762545e+00 3.0458525036468949e+00 0 1 0 -340 1 5 4.2499999999999999e-01 2.8949638088772307e+00 -1.2764531076970115e+01 1.1506995342547839e+00 0 1 0 -341 1 1 1.5750000000000000e+00 2.5033639442170603e+00 -1.0455467418500232e+01 -3.7644509063081699e-03 0 1 0 -342 1 2 2.1000000000000001e+00 1.7145883215431166e+00 -1.7829300701939800e+01 -2.7608958052170411e+00 0 1 0 -343 1 2 2.1000000000000001e+00 1.6912266037300405e+00 -1.1818422575268272e+01 -2.7688097307868276e+00 0 1 0 -344 1 3 -1.0500000000000000e+00 1.9120834625213252e+00 -8.9345130319058228e+00 -1.1428294669850914e+00 0 1 0 -345 1 3 -1.0500000000000000e+00 1.5563473338147098e+00 -1.1725560272130608e+01 -1.1440021351942580e+00 0 1 0 -346 1 4 -9.4999999999999996e-01 4.1971082670870832e+00 -1.0529108746921157e+01 -1.0139629452484886e+00 0 1 0 -347 1 3 -1.0500000000000000e+00 5.5464530705974475e+00 -1.2521352161841751e+01 -3.2426252532725606e+00 0 1 0 -348 1 3 -1.0500000000000000e+00 1.8036846786360634e+00 -1.0344146018525349e+01 -3.2448200263190197e+00 0 1 0 -349 1 3 -1.0500000000000000e+00 2.9567112736132568e+00 -1.2670269721125457e+01 -3.0528480141101975e+00 0 1 0 -350 1 5 4.2499999999999999e-01 4.7039259604937165e+00 -9.6502933808630385e+00 -1.1578284319124439e+00 0 1 0 -351 1 1 1.5750000000000000e+00 -1.0478724382672588e-01 -1.4938358402103905e+01 -3.7627223220813022e-03 0 1 0 -352 1 2 2.1000000000000001e+00 4.3227246375149999e+00 -1.3346393842097065e+01 -2.7608829004974371e+00 0 1 0 -353 1 2 2.1000000000000001e+00 4.2430757022707475e+00 -1.6301350005051795e+01 -2.7688226751901599e+00 0 1 0 -354 1 3 -1.0500000000000000e+00 4.4639095502810164e+00 -1.3417443754494391e+01 -1.1428177079403934e+00 0 1 0 -355 1 3 -1.0500000000000000e+00 4.1082036480419770e+00 -1.6208502117162574e+01 -1.1440139172301169e+00 0 1 0 -356 1 4 -9.4999999999999996e-01 1.5889500236856300e+00 -1.5012041124287654e+01 -1.0139477440142528e+00 0 1 0 -357 1 3 -1.0500000000000000e+00 2.9382903714053548e+00 -1.7004291605725765e+01 -3.2426100113030323e+00 0 1 0 -358 1 3 -1.0500000000000000e+00 4.3555145972073195e+00 -1.4827036933345422e+01 -3.2448327885333361e+00 0 1 0 -359 1 3 -1.0500000000000000e+00 5.5085820267482344e+00 -1.7153164911429155e+01 -3.0528642112304896e+00 0 1 0 -360 1 5 4.2499999999999999e-01 2.0957734077439056e+00 -1.4133159373854168e+01 -1.1577652912805814e+00 0 1 0 -361 1 1 1.5750000000000000e+00 7.6474140007788982e+00 -1.6442141104718459e+01 -3.2712422133958086e-03 0 1 0 -362 1 2 2.1000000000000001e+00 -1.2203827203511482e+01 -9.0683271450119296e+00 2.7538837322524401e+00 1 1 0 -363 1 2 2.1000000000000001e+00 -1.2180456882496275e+01 -1.5079188663398204e+01 2.7617712268273706e+00 1 1 0 -364 1 3 -1.0500000000000000e+00 8.2388195509416313e+00 -1.7962985321336554e+01 1.1357676242748713e+00 0 1 0 -365 1 3 -1.0500000000000000e+00 -1.2045609949867293e+01 -1.5172220042357347e+01 1.1370285985962134e+00 1 1 0 -366 1 4 -9.4999999999999996e-01 5.9537465861360772e+00 -1.6368425850235276e+01 1.0069194882915156e+00 0 1 0 -367 1 3 -1.0500000000000000e+00 4.6043271774073027e+00 -1.4376297983489385e+01 3.2357613671647218e+00 0 1 0 -368 1 3 -1.0500000000000000e+00 -1.2292747746102600e+01 -1.6553469124434326e+01 3.2376815492582445e+00 1 1 0 -369 1 3 -1.0500000000000000e+00 7.1940128452294942e+00 -1.4227408234827857e+01 3.0458373260631326e+00 0 1 0 -370 1 5 4.2499999999999999e-01 5.4468174222515913e+00 -1.7247378031857870e+01 1.1508392493771673e+00 0 1 0 -371 1 1 1.5750000000000000e+00 -1.0384424433456566e+01 -1.1959252659931799e+01 -3.2712770141074543e-03 1 1 0 -372 1 2 2.1000000000000001e+00 5.8280305242892041e+00 -1.3551239953281975e+01 2.7538838511391113e+00 0 1 0 -373 1 2 2.1000000000000001e+00 5.9077021357550628e+00 -1.0596251869748077e+01 2.7617756829546156e+00 0 1 0 -374 1 3 -1.0500000000000000e+00 5.6870104432353159e+00 -1.3480054174516480e+01 1.1357417030207291e+00 0 1 0 -375 1 3 -1.0500000000000000e+00 6.0425292729245470e+00 -1.0689281429519454e+01 1.1370466440112210e+00 0 1 0 -376 1 4 -9.4999999999999996e-01 -1.2078097104560454e+01 -1.1885492622672418e+01 1.0069102507731635e+00 1 1 0 -377 1 3 -1.0500000000000000e+00 7.2124666572537386e+00 -9.8933767032710165e+00 3.2357410803523212e+00 0 1 0 -378 1 3 -1.0500000000000000e+00 5.7954239936184990e+00 -1.2070583137752678e+01 3.2376828374688245e+00 0 1 0 -379 1 3 -1.0500000000000000e+00 4.6421588256009514e+00 -9.7445230635909930e+00 3.0458552390209626e+00 0 1 0 -380 1 5 4.2499999999999999e-01 8.0549852922256555e+00 -1.2764517907898643e+01 1.1508102027032923e+00 0 1 0 -381 1 1 1.5750000000000000e+00 7.6633730752544444e+00 -1.0455467693346659e+01 -3.7627462054388161e-03 0 1 0 -382 1 2 2.1000000000000001e+00 6.8745665434856029e+00 -1.7829291188991537e+01 -2.7608962744252388e+00 0 1 0 -383 1 2 2.1000000000000001e+00 6.8512147729773751e+00 -1.1818412840078709e+01 -2.7688138978399577e+00 0 1 0 -384 1 3 -1.0500000000000000e+00 7.0720780979908788e+00 -8.9345108816178023e+00 -1.1428117082690488e+00 0 1 0 -385 1 3 -1.0500000000000000e+00 6.7163521748302202e+00 -1.1725570009560613e+01 -1.1440096250283265e+00 0 1 0 -386 1 4 -9.4999999999999996e-01 -1.1282887950173640e+01 -1.0529096981501368e+01 -1.0139488174126754e+00 1 1 0 -387 1 3 -1.0500000000000000e+00 -9.9335717335547695e+00 -1.2521371532644960e+01 -3.2426313424611628e+00 1 1 0 -388 1 3 -1.0500000000000000e+00 6.9636832870116550e+00 -1.0344162343052757e+01 -3.2448254223620889e+00 0 1 0 -389 1 3 -1.0500000000000000e+00 8.1167231325051823e+00 -1.2670274185341015e+01 -3.0528503728012168e+00 0 1 0 -390 1 5 4.2499999999999999e-01 -1.0776053229517712e+01 -9.6502818959831345e+00 -1.1577296917059403e+00 1 1 0 -391 1 1 1.5750000000000000e+00 5.0552003785718238e+00 -1.4938350227169186e+01 -3.7677661155619546e-03 0 1 0 -392 1 2 2.1000000000000001e+00 -1.1157267005103233e+01 -1.3346383380724077e+01 -2.7608979565505667e+00 1 1 0 -393 1 2 2.1000000000000001e+00 -1.1236931699789672e+01 -1.6301360581610055e+01 -2.7688152480258648e+00 1 1 0 -394 1 3 -1.0500000000000000e+00 -1.1016106023998026e+01 -1.3417445610180295e+01 -1.1428064857394364e+00 1 1 0 -395 1 3 -1.0500000000000000e+00 -1.1371792023642708e+01 -1.6208498400003911e+01 -1.1440202314302645e+00 1 1 0 -396 1 4 -9.4999999999999996e-01 6.7489762870942691e+00 -1.5012008729518147e+01 -1.0139288201720564e+00 0 1 0 -397 1 3 -1.0500000000000000e+00 8.0983140651380410e+00 -1.7004276989823527e+01 -3.2426161247390830e+00 0 1 0 -398 1 3 -1.0500000000000000e+00 -1.1124489077265366e+01 -1.4827035967743710e+01 -3.2448153895310927e+00 1 1 0 -399 1 3 -1.0500000000000000e+00 -9.9714353978520460e+00 -1.7153153004547544e+01 -3.0528663070229056e+00 1 1 0 -400 1 5 4.2499999999999999e-01 7.2557948806931165e+00 -1.4133138343620868e+01 -1.1576144335907745e+00 0 1 0 -401 1 1 1.5750000000000000e+00 -7.8325987088646514e+00 -1.6442132655170560e+01 -3.2768281810451327e-03 1 1 0 -402 1 2 2.1000000000000001e+00 -7.0438329831012698e+00 -9.0683380704114676e+00 2.7538987477440742e+00 1 1 0 -403 1 2 2.1000000000000001e+00 -7.0204476328257197e+00 -1.5079178983018382e+01 2.7617637042415826e+00 1 1 0 -404 1 3 -1.0500000000000000e+00 -7.2411652176105106e+00 -1.7962983339974674e+01 1.1357551346155645e+00 1 1 0 -405 1 3 -1.0500000000000000e+00 -6.8856151200206943e+00 -1.5172222779836469e+01 1.1370348917642197e+00 1 1 0 -406 1 4 -9.4999999999999996e-01 -9.5262277963353625e+00 -1.6368394589307186e+01 1.0069374583931676e+00 1 1 0 -407 1 3 -1.0500000000000000e+00 -1.0875647155440383e+01 -1.4376281875079192e+01 3.2357554794971310e+00 1 1 0 -408 1 3 -1.0500000000000000e+00 -7.1327446774404644e+00 -1.6553469216702961e+01 3.2376642450792890e+00 1 1 0 -409 1 3 -1.0500000000000000e+00 -8.2859711614561924e+00 -1.4227419710872399e+01 3.0458397444963783e+00 1 1 0 -410 1 5 4.2499999999999999e-01 -1.0033162577689296e+01 -1.7247357569713181e+01 1.1509820667296005e+00 1 1 0 -411 1 1 1.5750000000000000e+00 -5.2244330327843302e+00 -1.1959252733066059e+01 -3.2723594124206556e-03 1 1 0 -412 1 2 2.1000000000000001e+00 -9.6519914181098638e+00 -1.3551231558286446e+01 2.7538839123825358e+00 1 1 0 -413 1 2 2.1000000000000001e+00 -9.5723092587508365e+00 -1.0596241527882761e+01 2.7617710710465815e+00 1 1 0 -414 1 3 -1.0500000000000000e+00 -9.7929945069961253e+00 -1.3480051985547533e+01 1.1357587446241677e+00 1 1 0 -415 1 3 -1.0500000000000000e+00 -9.4374662927311146e+00 -1.0689290902241463e+01 1.1370397263922278e+00 1 1 0 -416 1 4 -9.4999999999999996e-01 -6.9181032886730494e+00 -1.1885507237050097e+01 1.0068948319789737e+00 1 1 0 -417 1 3 -1.0500000000000000e+00 -8.2675100232664320e+00 -9.8933578612205579e+00 3.2357470634817265e+00 1 1 0 -418 1 3 -1.0500000000000000e+00 -9.6845773759049134e+00 -1.2070598688698091e+01 3.2376769561759993e+00 1 1 0 -419 1 3 -1.0500000000000000e+00 -1.0837827580632311e+01 -9.7445282375445217e+00 3.0458527070702921e+00 1 1 0 -420 1 5 4.2499999999999999e-01 -7.4250361097992954e+00 -1.2764530721822616e+01 1.1507012617503953e+00 1 1 0 -421 1 1 1.5750000000000000e+00 -7.8166360353398296e+00 -1.0455467317595781e+01 -3.7646759390668194e-03 1 1 0 -422 1 2 2.1000000000000001e+00 -8.6054113356515174e+00 -1.7829300655592274e+01 -2.7608957051851020e+00 1 1 0 -423 1 2 2.1000000000000001e+00 -8.6287733711788945e+00 -1.1818422307923180e+01 -2.7688097450440914e+00 1 1 0 -424 1 3 -1.0500000000000000e+00 -8.4079164620832287e+00 -8.9345124902081920e+00 -1.1428294249997002e+00 1 1 0 -425 1 3 -1.0500000000000000e+00 -8.7636527884255369e+00 -1.1725560774598819e+01 -1.1440020134876807e+00 1 1 0 -426 1 4 -9.4999999999999996e-01 -6.1228919404979258e+00 -1.0529109537709003e+01 -1.0139632037918567e+00 1 1 0 -427 1 3 -1.0500000000000000e+00 -4.7735465425364261e+00 -1.2521351770250622e+01 -3.2426247858741188e+00 1 1 0 -428 1 3 -1.0500000000000000e+00 -8.5163154973470530e+00 -1.0344146339090138e+01 -3.2448207144857530e+00 1 1 0 -429 1 3 -1.0500000000000000e+00 -7.3632888784654300e+00 -1.2670269883876202e+01 -3.0528477722057836e+00 1 1 0 -430 1 5 4.2499999999999999e-01 -5.6160742944858129e+00 -9.6502936361410168e+00 -1.1578310235666027e+00 1 1 0 -431 1 1 1.5750000000000000e+00 -1.0424787313698658e+01 -1.4938358580151561e+01 -3.7626122635874282e-03 1 1 0 -432 1 2 2.1000000000000001e+00 -5.9972755539468423e+00 -1.3346393742894751e+01 -2.7608831402800682e+00 1 1 0 -433 1 2 2.1000000000000001e+00 -6.0769244076824771e+00 -1.6301350451987137e+01 -2.7688226495145400e+00 1 1 0 -434 1 3 -1.0500000000000000e+00 -5.8560904185150529e+00 -1.3417443741594207e+01 -1.1428180894157531e+00 1 1 0 -435 1 3 -1.0500000000000000e+00 -6.2117965092638689e+00 -1.6208501770452195e+01 -1.1440141749286337e+00 1 1 0 -436 1 4 -9.4999999999999996e-01 -8.7310499877968475e+00 -1.5012041076519363e+01 -1.0139476923019792e+00 1 1 0 -437 1 3 -1.0500000000000000e+00 -7.3817102540261006e+00 -1.7004291596432033e+01 -3.2426101124990616e+00 1 1 0 -438 1 3 -1.0500000000000000e+00 -5.9644854490417938e+00 -1.4827036400082546e+01 -3.2448326548745783e+00 1 1 0 -439 1 3 -1.0500000000000000e+00 -4.8114176926363816e+00 -1.7153165071890044e+01 -3.0528643435988796e+00 1 1 0 -440 1 5 4.2499999999999999e-01 -8.2242264630694635e+00 -1.4133159042780628e+01 -1.1577644578312860e+00 1 1 0 -441 1 1 1.5750000000000000e+00 -2.6725860454923716e+00 -1.6442140979377413e+01 -3.2715785717503110e-03 1 1 0 -442 1 2 2.1000000000000001e+00 -1.8838268726076954e+00 -9.0683274167193400e+00 2.7538838673764054e+00 1 1 0 -443 1 2 2.1000000000000001e+00 -1.8604569744326529e+00 -1.5079188467653989e+01 2.7617711436367749e+00 1 1 0 -444 1 3 -1.0500000000000000e+00 -2.0811803094950516e+00 -1.7962984553215737e+01 1.1357676790794518e+00 1 1 0 -445 1 3 -1.0500000000000000e+00 -1.7256099469169630e+00 -1.5172220506209625e+01 1.1370290834149568e+00 1 1 0 -446 1 4 -9.4999999999999996e-01 -4.3662535944850545e+00 -1.6368426374995096e+01 1.0069192163709406e+00 1 1 0 -447 1 3 -1.0500000000000000e+00 -5.7156724303722353e+00 -1.4376297686094702e+01 3.2357616060536500e+00 1 1 0 -448 1 3 -1.0500000000000000e+00 -1.9727476878083472e+00 -1.6553469357260379e+01 3.2376806823000805e+00 1 1 0 -449 1 3 -1.0500000000000000e+00 -3.1259875402225248e+00 -1.4227408307170990e+01 3.0458375072317931e+00 1 1 0 -450 1 5 4.2499999999999999e-01 -4.8731826994398277e+00 -1.7247378112483663e+01 1.1508372651166567e+00 1 1 0 -451 1 1 1.5750000000000000e+00 -6.4424497122509194e-02 -1.1959252857304573e+01 -3.2711003613989931e-03 1 1 0 -452 1 2 2.1000000000000001e+00 -4.4919697275807282e+00 -1.3551239499892894e+01 2.7538835130193178e+00 1 1 0 -453 1 2 2.1000000000000001e+00 -4.4122980632105389e+00 -1.0596252507809716e+01 2.7617758459985193e+00 1 1 0 -454 1 3 -1.0500000000000000e+00 -4.6329894753811018e+00 -1.3480054441043414e+01 1.1357411616494293e+00 1 1 0 -455 1 3 -1.0500000000000000e+00 -4.2774708277944749e+00 -1.0689280809016804e+01 1.1370461840218962e+00 1 1 0 -456 1 4 -9.4999999999999996e-01 -1.7580973201776757e+00 -1.1885492934621453e+01 1.0069101873652162e+00 1 1 0 -457 1 3 -1.0500000000000000e+00 -3.1075343280476124e+00 -9.8933768713007080e+00 3.2357409855029609e+00 1 1 0 -458 1 3 -1.0500000000000000e+00 -4.5245759850934562e+00 -1.2070582453780252e+01 3.2376832536971811e+00 1 1 0 -459 1 3 -1.0500000000000000e+00 -5.6778406227074374e+00 -9.7445233282126615e+00 3.0458553561637753e+00 1 1 0 -460 1 5 4.2499999999999999e-01 -2.2650147285034503e+00 -1.2764517807380475e+01 1.1508095218779513e+00 1 1 0 -461 1 1 1.5750000000000000e+00 -2.6566267712573959e+00 -1.0455467754355197e+01 -3.7628651117174172e-03 1 1 0 -462 1 2 2.1000000000000001e+00 -3.4454330497575922e+00 -1.7829291374521500e+01 -2.7608959935398278e+00 1 1 0 -463 1 2 2.1000000000000001e+00 -3.4687847465182164e+00 -1.1818412640485393e+01 -2.7688139713348265e+00 1 1 0 -464 1 3 -1.0500000000000000e+00 -3.2479222138107549e+00 -8.9345108165402163e+00 -1.1428114190548300e+00 1 1 0 -465 1 3 -1.0500000000000000e+00 -3.6036483967722068e+00 -1.1725569959668695e+01 -1.1440097904583197e+00 1 1 0 -466 1 4 -9.4999999999999996e-01 -9.6288746071596698e-01 -1.0529096622270014e+01 -1.0139486175176753e+00 1 1 0 -467 1 3 -1.0500000000000000e+00 3.8642758075409844e-01 -1.2521371796834121e+01 -3.2426314793729176e+00 1 1 0 -468 1 3 -1.0500000000000000e+00 -3.3563171807987331e+00 -1.0344162816602951e+01 -3.2448256742559547e+00 1 1 0 -469 1 3 -1.0500000000000000e+00 -2.2032768171139132e+00 -1.2670274183335055e+01 -3.0528507026798888e+00 1 1 0 -470 1 5 4.2499999999999999e-01 -4.5605310305733937e-01 -9.6502815620110756e+00 -1.1577280526341962e+00 1 1 0 -471 1 1 1.5750000000000000e+00 -5.2647994943095480e+00 -1.4938350193627970e+01 -3.7676882139958678e-03 1 1 0 -472 1 2 2.1000000000000001e+00 -8.3726684387525907e-01 -1.3346383679818349e+01 -2.7608978380764615e+00 1 1 0 -473 1 2 2.1000000000000001e+00 -9.1693231635642825e-01 -1.6301360191682914e+01 -2.7688154041374480e+00 1 1 0 -474 1 3 -1.0500000000000000e+00 -6.9610597467096902e-01 -1.3417445449864154e+01 -1.1428062509418382e+00 1 1 0 -475 1 3 -1.0500000000000000e+00 -1.0517917472121407e+00 -1.6208498767457716e+01 -1.1440198218448696e+00 1 1 0 -476 1 4 -9.4999999999999996e-01 -3.5710237330207564e+00 -1.5012008309322455e+01 -1.0139288908475432e+00 1 1 0 -477 1 3 -1.0500000000000000e+00 -2.2216854152876397e+00 -1.7004276658189614e+01 -3.2426163592502810e+00 1 1 0 -478 1 3 -1.0500000000000000e+00 -8.0448898995668117e-01 -1.4827035666840533e+01 -3.2448155765297635e+00 1 1 0 -479 1 3 -1.0500000000000000e+00 3.4856436060504770e-01 -1.7153153014747577e+01 -3.0528662662661059e+00 1 1 0 -480 1 5 4.2499999999999999e-01 -3.0642049652000143e+00 -1.4133138272087391e+01 -1.1576140022296713e+00 1 1 0 -481 1 1 1.5750000000000000e+00 2.5437428443050614e+00 -7.4763290654367793e+00 -3.2727843275015545e-03 0 1 0 -482 1 2 2.1000000000000001e+00 3.3325143365597025e+00 -1.0250025401234808e-01 2.7538899722376140e+00 0 1 0 -483 1 2 2.1000000000000001e+00 3.3558821357468283e+00 -6.1133543212193615e+00 2.7617600520107199e+00 0 1 0 -484 1 3 -1.0500000000000000e+00 3.1351821115936183e+00 -8.9971651740225838e+00 1.1357391106399142e+00 0 1 0 -485 1 3 -1.0500000000000000e+00 3.4907159605798821e+00 -6.2063934276813146e+00 1.1370368516085225e+00 0 1 0 -486 1 4 -9.4999999999999996e-01 8.5006829935557526e-01 -7.4026295803576776e+00 1.0068913510959483e+00 0 1 0 -487 1 3 -1.0500000000000000e+00 -4.9932070053753819e-01 -5.4104540265425136e+00 3.2357550151254983e+00 0 1 0 -488 1 3 -1.0500000000000000e+00 3.2435836625637098e+00 -7.5876734045415208e+00 3.2376942410532372e+00 0 1 0 -489 1 3 -1.0500000000000000e+00 2.0903637933720240e+00 -5.2615953966090157e+00 3.0458381487111073e+00 0 1 0 -490 1 5 4.2499999999999999e-01 3.4314579950012281e-01 -8.2816361682866866e+00 1.1506285010010053e+00 0 1 0 -491 1 1 1.5750000000000000e+00 5.1519007920822677e+00 -2.9934055851345569e+00 -3.2755181750694362e-03 0 1 0 -492 1 2 2.1000000000000001e+00 7.2433516655473085e-01 -4.5854323953349994e+00 2.7538940303405468e+00 0 1 0 -493 1 2 2.1000000000000001e+00 8.0403844907513111e-01 -1.6304342777080656e+00 2.7617692133861844e+00 0 1 0 -494 1 3 -1.0500000000000000e+00 5.8332753620582878e-01 -4.5142386575707967e+00 1.1357715487752991e+00 0 1 0 -495 1 3 -1.0500000000000000e+00 9.3888358238824132e-01 -1.7234842555474330e+00 1.1370322770517962e+00 0 1 0 -496 1 4 -9.4999999999999996e-01 3.4582624938324464e+00 -2.9196606692347373e+00 1.0069287098097952e+00 0 1 0 -497 1 3 -1.0500000000000000e+00 2.1088452933105515e+00 -9.2754381224241911e-01 3.2357558337759187e+00 0 1 0 -498 1 3 -1.0500000000000000e+00 6.9175890168239285e-01 -3.1047451781196980e+00 3.2376601672098353e+00 0 1 0 -499 1 3 -1.0500000000000000e+00 -4.6147998751177077e-01 -7.7869228339827146e-01 3.0458447706244485e+00 0 1 0 -500 1 5 4.2499999999999999e-01 2.9513209410617236e+00 -3.7986262825283390e+00 1.1509346722221778e+00 0 1 0 -501 1 1 1.5750000000000000e+00 2.5597054807324575e+00 -1.4896328202162827e+00 -3.7641697671766394e-03 0 1 0 -502 1 2 2.1000000000000001e+00 1.7709229018856441e+00 -8.8634561270471117e+00 -2.7609031839459668e+00 0 1 0 -503 1 2 2.1000000000000001e+00 1.7475743368804846e+00 -2.8526187449971925e+00 -2.7688169163355161e+00 0 1 0 -504 1 3 -1.0500000000000000e+00 1.9684142136564855e+00 3.1291433226034115e-02 -1.1428293832068732e+00 0 1 0 -505 1 3 -1.0500000000000000e+00 1.6126991068964927e+00 -2.7597528108143781e+00 -1.1440099493613740e+00 0 1 0 -506 1 4 -9.4999999999999996e-01 4.2534440005880345e+00 -1.5633162907652967e+00 -1.0139670411605106e+00 0 1 0 -507 1 3 -1.0500000000000000e+00 5.6028070706999085e+00 -3.5555353752400194e+00 -3.2426138519003480e+00 0 1 0 -508 1 3 -1.0500000000000000e+00 1.8600138603729519e+00 -1.3783113095641859e+00 -3.2448093859554312e+00 0 1 0 -509 1 3 -1.0500000000000000e+00 3.0130640434981846e+00 -3.7044268744313076e+00 -3.0528611149824840e+00 0 1 0 -510 1 5 4.2499999999999999e-01 4.7602624282210773e+00 -6.8447111963222085e-01 -1.1578959465317258e+00 0 1 0 -511 1 1 1.5750000000000000e+00 -4.8461934562219255e-02 -5.9725283181091999e+00 -3.7657186053703384e-03 0 1 0 -512 1 2 2.1000000000000001e+00 4.3790687596779545e+00 -4.3805774348320163e+00 -2.7608834156531588e+00 0 1 0 -513 1 2 2.1000000000000001e+00 4.2994058725582978e+00 -7.3355166213734044e+00 -2.7688158506083589e+00 0 1 0 -514 1 3 -1.0500000000000000e+00 4.5202382580472147e+00 -4.4516060149497640e+00 -1.1428063857974333e+00 0 1 0 -515 1 3 -1.0500000000000000e+00 4.1645302012946015e+00 -7.2426741661367142e+00 -1.1440101789046420e+00 0 1 0 -516 1 4 -9.4999999999999996e-01 1.6453112563615342e+00 -6.0461586199490434e+00 -1.0139128829819715e+00 0 1 0 -517 1 3 -1.0500000000000000e+00 2.9946194711543797e+00 -8.0384682128749585e+00 -3.2426160823192296e+00 0 1 0 -518 1 3 -1.0500000000000000e+00 4.4118575725849478e+00 -5.8612005270691547e+00 -3.2448606834731235e+00 0 1 0 -519 1 3 -1.0500000000000000e+00 5.5649056084454109e+00 -8.1873553093095772e+00 -3.0528543077062977e+00 0 1 0 -520 1 5 4.2499999999999999e-01 2.1521250351535262e+00 -5.1672641173132057e+00 -1.1574751396834095e+00 0 1 0 -521 1 1 1.5750000000000000e+00 7.7037558991738599e+00 -7.4763378860718905e+00 -3.2674777746422023e-03 0 1 0 -522 1 2 2.1000000000000001e+00 -1.2147479540675596e+01 -1.0248904685654736e-01 2.7538750591972576e+00 1 1 0 -523 1 2 2.1000000000000001e+00 -1.2124126537284520e+01 -6.1133637887965655e+00 2.7617676941196780e+00 1 1 0 -524 1 3 -1.0500000000000000e+00 8.2951661598915436e+00 -8.9971668311599462e+00 1.1357516866908792e+00 0 1 0 -525 1 3 -1.0500000000000000e+00 -1.1989279027148052e+01 -6.2063908589686090e+00 1.1370303900129706e+00 1 1 0 -526 1 4 -9.4999999999999996e-01 6.0100419731521590e+00 -7.4026621880566204e+00 1.0068725663833540e+00 0 1 0 -527 1 3 -1.0500000000000000e+00 4.6606516613797240e+00 -5.4104711479323324e+00 3.2357607347980188e+00 0 1 0 -528 1 3 -1.0500000000000000e+00 -1.2236419929777080e+01 -7.5876744779089300e+00 3.2377114436177603e+00 1 1 0 -529 1 3 -1.0500000000000000e+00 7.2503475140887517e+00 -5.2615834535037163e+00 3.0458350831799024e+00 0 1 0 -530 1 5 4.2499999999999999e-01 5.5031248162859363e+00 -8.2816586669648764e+00 1.1504775671503982e+00 0 1 0 -531 1 1 1.5750000000000000e+00 -1.0328090736276579e+01 -2.9934052134837739e+00 -3.2742342788942835e-03 1 1 0 -532 1 2 2.1000000000000001e+00 5.8843577352361969e+00 -4.5854409933780982e+00 2.7538938006927332e+00 0 1 0 -533 1 2 2.1000000000000001e+00 5.9640491212179221e+00 -1.6304443968939282e+00 2.7617738948866943e+00 0 1 0 -534 1 3 -1.0500000000000000e+00 5.7433322530522553e+00 -4.5142405415325584e+00 1.1357549006778278e+00 0 1 0 -535 1 3 -1.0500000000000000e+00 6.0988792426183096e+00 -1.7234752280405523e+00 1.1370394148745575e+00 0 1 0 -536 1 4 -9.4999999999999996e-01 -1.2021730767319838e+01 -2.9196445773831172e+00 1.0069449673131015e+00 1 1 0 -537 1 3 -1.0500000000000000e+00 7.2688224225511284e+00 -9.2756193808273579e-01 3.2357497168675291e+00 0 1 0 -538 1 3 -1.0500000000000000e+00 5.8517605054545925e+00 -3.1047288251616880e+00 3.2376660627521652e+00 0 1 0 -539 1 3 -1.0500000000000000e+00 4.6985063778664689e+00 -7.7868717608841109e-01 3.0458472389085003e+00 0 1 0 -540 1 5 4.2499999999999999e-01 8.1113434738929335e+00 -3.7986119805910690e+00 1.1510507048952583e+00 0 1 0 -541 1 1 1.5750000000000000e+00 7.7197148836677840e+00 -1.4896332681099977e+00 -3.7622932616550031e-03 0 1 0 -542 1 2 2.1000000000000001e+00 6.9309006873999373e+00 -8.8634465516607222e+00 -2.7609032216192340e+00 0 1 0 -543 1 2 2.1000000000000001e+00 6.9075617205026099e+00 -2.8526096435656072e+00 -2.7688210573252867e+00 0 1 0 -544 1 3 -1.0500000000000000e+00 7.1284082898495029e+00 3.1293595601468382e-02 -1.1428111723249756e+00 0 1 0 -545 1 3 -1.0500000000000000e+00 6.7727039169662824e+00 -2.7597629413404334e+00 -1.1440175444233223e+00 0 1 0 -546 1 4 -9.4999999999999996e-01 -1.1226552655481083e+01 -1.5633049519995765e+00 -1.0139534286726537e+00 1 1 0 -547 1 3 -1.0500000000000000e+00 -9.8772181002317527e+00 -3.5555551458176851e+00 -3.2426197963436429e+00 1 1 0 -548 1 3 -1.0500000000000000e+00 7.0200123964331773e+00 -1.3783273811475922e+00 -3.2448142845091841e+00 0 1 0 -549 1 3 -1.0500000000000000e+00 8.1730763646192806e+00 -3.7044313459903186e+00 -3.0528640321362017e+00 0 1 0 -550 1 5 4.2499999999999999e-01 -1.0719717437091941e+01 -6.8445981575252191e-01 -1.1577998396399334e+00 1 1 0 -551 1 1 1.5750000000000000e+00 5.1115253237510885e+00 -5.9725200527678375e+00 -3.7707777933437825e-03 0 1 0 -552 1 2 2.1000000000000001e+00 -1.1100923034835599e+01 -4.3805669323581800e+00 -2.7608982673286873e+00 1 1 0 -553 1 2 2.1000000000000001e+00 -1.1180601899143772e+01 -7.3355275535629865e+00 -2.7688084214282824e+00 1 1 0 -554 1 3 -1.0500000000000000e+00 -1.0959777639293579e+01 -4.4516079634311403e+00 -1.1427954297313665e+00 1 1 0 -555 1 3 -1.0500000000000000e+00 -1.1315465003428104e+01 -7.2426703566200885e+00 -1.1440162616625038e+00 1 1 0 -556 1 4 -9.4999999999999996e-01 6.8053384876524348e+00 -6.0461247515223633e+00 -1.0138928297727023e+00 0 1 0 -557 1 3 -1.0500000000000000e+00 8.1546442346681758e+00 -8.0384528996609212e+00 -3.2426220385092064e+00 0 1 0 -558 1 3 -1.0500000000000000e+00 -1.1068145943296541e+01 -5.8611992032321663e+00 -3.2448430262419521e+00 1 1 0 -559 1 3 -1.0500000000000000e+00 -9.9151118491047789e+00 -8.1873431305477204e+00 -3.0528565804834749e+00 1 1 0 -560 1 5 4.2499999999999999e-01 7.3121473928702372e+00 -5.1672412452561431e+00 -1.1573163074437751e+00 0 1 0 -561 1 1 1.5750000000000000e+00 -7.7762569905599648e+00 -7.4763292210563481e+00 -3.2729572907843618e-03 1 1 0 -562 1 2 2.1000000000000001e+00 -6.9874852603855171e+00 -1.0249995181859717e-01 2.7538899177545808e+00 1 1 0 -563 1 2 2.1000000000000001e+00 -6.9641170956182634e+00 -6.1133540075035597e+00 2.7617599752000341e+00 1 1 0 -564 1 3 -1.0500000000000000e+00 -7.1848180581083465e+00 -8.9971648978059235e+00 1.1357392622772089e+00 1 1 0 -565 1 3 -1.0500000000000000e+00 -6.8292846322454803e+00 -6.2063938248720696e+00 1.1370367173496518e+00 1 1 0 -566 1 4 -9.4999999999999996e-01 -9.4699316241975442e+00 -7.4026298681375042e+00 1.0068912603839042e+00 1 1 0 -567 1 3 -1.0500000000000000e+00 -1.0819321546951546e+01 -5.4104542960664528e+00 3.2357547946170993e+00 1 1 0 -568 1 3 -1.0500000000000000e+00 -7.0764169632945553e+00 -7.5876741559189220e+00 3.2376938897616760e+00 1 1 0 -569 1 3 -1.0500000000000000e+00 -8.2296362096715843e+00 -5.2615952565138215e+00 3.0458377616137984e+00 1 1 0 -570 1 5 4.2499999999999999e-01 -9.9768543297092513e+00 -8.2816365190055947e+00 1.1506270799920468e+00 1 1 0 -571 1 1 1.5750000000000000e+00 -5.1680993369879111e+00 -2.9934054729353790e+00 -3.2753649121453066e-03 1 1 0 -572 1 2 2.1000000000000001e+00 -9.5956648943371743e+00 -4.5854329909724871e+00 2.7538940335382165e+00 1 1 0 -573 1 2 2.1000000000000001e+00 -9.5159624152356610e+00 -1.6304339314138971e+00 2.7617691698610329e+00 1 1 0 -574 1 3 -1.0500000000000000e+00 -9.7366726615179306e+00 -4.5142384775009283e+00 1.1357719096965848e+00 1 1 0 -575 1 3 -1.0500000000000000e+00 -9.3811162155192349e+00 -1.7234845347046139e+00 1.1370325264004357e+00 1 1 0 -576 1 4 -9.4999999999999996e-01 -6.8617368272101302e+00 -2.9196588804018919e+00 1.0069291746774116e+00 1 1 0 -577 1 3 -1.0500000000000000e+00 -8.2111540032415924e+00 -9.2754316282725568e-01 3.2357553994951456e+00 1 1 0 -578 1 3 -1.0500000000000000e+00 -9.6282410766231621e+00 -3.1047445967403267e+00 3.2376600241271269e+00 1 1 0 -579 1 3 -1.0500000000000000e+00 -1.0781479595857174e+01 -7.7869267945188980e-01 3.0458446930343310e+00 1 1 0 -580 1 5 4.2499999999999999e-01 -7.3686786477224917e+00 -3.7986256968323495e+00 1.1509396217374359e+00 1 1 0 -581 1 1 1.5750000000000000e+00 -7.7602941835095152e+00 -1.4896327770942186e+00 -3.7645023786900822e-03 1 1 0 -582 1 2 2.1000000000000001e+00 -8.5490769143033329e+00 -8.8634560300473773e+00 -2.7609027560125616e+00 1 1 0 -583 1 2 2.1000000000000001e+00 -8.5724260529654899e+00 -2.8526187459454775e+00 -2.7688169994275027e+00 1 1 0 -584 1 3 -1.0500000000000000e+00 -8.3515860468649610e+00 3.1291775896583829e-02 -1.1428289259283630e+00 1 1 0 -585 1 3 -1.0500000000000000e+00 -8.7073012018141256e+00 -2.7597534138343551e+00 -1.1440099773059345e+00 1 1 0 -586 1 4 -9.4999999999999996e-01 -6.0665567086335894e+00 -1.5633179445508141e+00 -1.0139679887751143e+00 1 1 0 -587 1 3 -1.0500000000000000e+00 -4.7171927908837130e+00 -3.5555352046377813e+00 -3.2426132222785551e+00 1 1 0 -588 1 3 -1.0500000000000000e+00 -8.4599863641973911e+00 -1.3783117280857766e+00 -3.2448099336917053e+00 1 1 0 -589 1 3 -1.0500000000000000e+00 -7.3069362230082264e+00 -3.7044270077421775e+00 -3.0528612833069495e+00 1 1 0 -590 1 5 4.2499999999999999e-01 -5.5597382734660146e+00 -6.8447230495398514e-01 -1.1579029590360665e+00 1 1 0 -591 1 1 1.5750000000000000e+00 -1.0368462013809715e+01 -5.9725285486244175e+00 -3.7655886569041286e-03 1 1 0 -592 1 2 2.1000000000000001e+00 -5.9409312949912598e+00 -4.3805774677999114e+00 -2.7608833532589667e+00 1 1 0 -593 1 2 2.1000000000000001e+00 -6.0205944500317869e+00 -7.3355174587776268e+00 -2.7688156713870473e+00 1 1 0 -594 1 3 -1.0500000000000000e+00 -5.7997617184336399e+00 -4.4516060170058882e+00 -1.1428071651994216e+00 1 1 0 -595 1 3 -1.0500000000000000e+00 -6.1554699263342227e+00 -7.2426738849434500e+00 -1.1440103605752991e+00 1 1 0 -596 1 4 -9.4999999999999996e-01 -8.6746885506377929e+00 -6.0461581043709547e+00 -1.0139124232049213e+00 1 1 0 -597 1 3 -1.0500000000000000e+00 -7.3253810049358634e+00 -8.0384681188500480e+00 -3.2426161668381255e+00 1 1 0 -598 1 3 -1.0500000000000000e+00 -5.9081425026458234e+00 -5.8611994345077498e+00 -3.2448607171530028e+00 1 1 0 -599 1 3 -1.0500000000000000e+00 -4.7550940216043962e+00 -8.1873556577152282e+00 -3.0528543383775428e+00 1 1 0 -600 1 5 4.2499999999999999e-01 -8.1678745921157159e+00 -5.1672631870311587e+00 -1.1574715624876504e+00 1 1 0 -601 1 1 1.5750000000000000e+00 -2.6162439088328018e+00 -7.4763377348727964e+00 -3.2678364488045730e-03 1 1 0 -602 1 2 2.1000000000000001e+00 -1.8274788871067358e+00 -1.0248873805953806e-01 2.7538753342260538e+00 1 1 0 -603 1 2 2.1000000000000001e+00 -1.8041266480770410e+00 -6.1133634617173769e+00 2.7617674223332180e+00 1 1 0 -604 1 3 -1.0500000000000000e+00 -2.0248338826643852e+00 -8.9971663387231171e+00 1.1357520841744879e+00 1 1 0 -605 1 3 -1.0500000000000000e+00 -1.6692792021522784e+00 -6.2063914432239784e+00 1.1370306179598053e+00 1 1 0 -606 1 4 -9.4999999999999996e-01 -4.3099581032796426e+00 -7.4026628298493691e+00 1.0068721120843129e+00 1 1 0 -607 1 3 -1.0500000000000000e+00 -5.6593477071002427e+00 -5.4104706586807598e+00 3.2357612259566810e+00 1 1 0 -608 1 3 -1.0500000000000000e+00 -1.9164199611639763e+00 -7.5876744403480334e+00 3.2377106688994672e+00 1 1 0 -609 1 3 -1.0500000000000000e+00 -3.0696526734579912e+00 -5.2615837585529661e+00 3.0458351423823995e+00 1 1 0 -610 1 5 4.2499999999999999e-01 -4.8168753766812173e+00 -8.2816588556170441e+00 1.1504750354406177e+00 1 1 0 -611 1 1 1.5750000000000000e+00 -8.0907518766384356e-03 -2.9934052375443336e+00 -3.2740227413210476e-03 1 1 0 -612 1 2 2.1000000000000001e+00 -4.4356427267419249e+00 -4.5854410157732630e+00 2.7538936803516236e+00 1 1 0 -613 1 2 2.1000000000000001e+00 -4.3559506708301869e+00 -1.6304450860677413e+00 2.7617742017561611e+00 1 1 0 -614 1 3 -1.0500000000000000e+00 -4.5766676861845337e+00 -4.5142406278999356e+00 1.1357540075340431e+00 1 1 0 -615 1 3 -1.0500000000000000e+00 -4.2211208998235374e+00 -1.7234746477014085e+00 1.1370391085097005e+00 1 1 0 -616 1 4 -9.4999999999999996e-01 -1.7017308095141530e+00 -2.9196445057488543e+00 1.0069450576127146e+00 1 1 0 -617 1 3 -1.0500000000000000e+00 -3.0511784689434727e+00 -9.2756217522688189e-01 3.2357492997903989e+00 1 1 0 -618 1 3 -1.0500000000000000e+00 -4.4682395324586812e+00 -3.1047276939647919e+00 3.2376661470048926e+00 1 1 0 -619 1 3 -1.0500000000000000e+00 -5.6214933347898324e+00 -7.7868769293100115e-01 3.0458474426563953e+00 1 1 0 -620 1 5 4.2499999999999999e-01 -2.2086564507405413e+00 -3.7986117927510303e+00 1.1510515474004510e+00 1 1 0 -621 1 1 1.5750000000000000e+00 -2.6002847675544425e+00 -1.4896332839062900e+00 -3.7624608697708339e-03 1 1 0 -622 1 2 2.1000000000000001e+00 -3.3890989903510782e+00 -8.8634464820416135e+00 -2.7609031570252727e+00 1 1 0 -623 1 2 2.1000000000000001e+00 -3.4124375560886504e+00 -2.8526087485993727e+00 -2.7688212850156475e+00 1 1 0 -624 1 3 -1.0500000000000000e+00 -3.1915918895382411e+00 3.1293558407224253e-02 -1.1428108351966415e+00 1 1 0 -625 1 3 -1.0500000000000000e+00 -3.5472968461038539e+00 -2.7597630593752758e+00 -1.1440177254266484e+00 1 1 0 -626 1 4 -9.4999999999999996e-01 -9.0655254049773504e-01 -1.5633051342915110e+00 -1.0139535250007192e+00 1 1 0 -627 1 3 -1.0500000000000000e+00 4.4278040052260614e-01 -3.5555559093274116e+00 -3.2426200340769729e+00 1 1 0 -628 1 3 -1.0500000000000000e+00 -3.2999882795906919e+00 -1.3783286609239447e+00 -3.2448144397936769e+00 1 1 0 -629 1 3 -1.0500000000000000e+00 -2.1469233743245475e+00 -3.7044316792199190e+00 -3.0528642030739999e+00 1 1 0 -630 1 5 4.2499999999999999e-01 -3.9971760590508154e-01 -6.8446030330258623e-01 -1.1578011616844854e+00 1 1 0 -631 1 1 1.5750000000000000e+00 -5.2084747049386433e+00 -5.9725199350010367e+00 -3.7706577197997859e-03 1 1 0 -632 1 2 2.1000000000000001e+00 -7.8092247342052268e-01 -4.3805669254643291e+00 -2.7608982903115145e+00 1 1 0 -633 1 2 2.1000000000000001e+00 -8.6060231852112956e-01 -7.3355272980120905e+00 -2.7688084165575599e+00 1 1 0 -634 1 3 -1.0500000000000000e+00 -6.3977768288892811e-01 -4.4516079890501903e+00 -1.1427953392839356e+00 1 1 0 -635 1 3 -1.0500000000000000e+00 -9.9546482780511170e-01 -7.2426706927175317e+00 -1.1440163037674758e+00 1 1 0 -636 1 4 -9.4999999999999996e-01 -3.5146616662975276e+00 -6.0461244961827063e+00 -1.0138928485202694e+00 1 1 0 -637 1 3 -1.0500000000000000e+00 -2.1653552296849572e+00 -8.0384524245545155e+00 -3.2426224857573978e+00 1 1 0 -638 1 3 -1.0500000000000000e+00 -7.4814595915323245e-01 -5.8611986535726803e+00 -3.2448432145562878e+00 1 1 0 -639 1 3 -1.0500000000000000e+00 4.0488791617551101e-01 -8.1873432387570784e+00 -3.0528565988277272e+00 1 1 0 -640 1 5 4.2499999999999999e-01 -3.0078522733471900e+00 -5.1672408708798834e+00 -1.1573153446034699e+00 1 1 0 -641 1 1 1.5750000000000000e+00 9.0335153204797436e-01 1.3077850374052922e+00 9.1936372083344011e+00 0 0 0 -642 1 2 2.1000000000000001e+00 5.0860371803135038e+00 9.0452875324800992e+00 -6.4424554626411297e+00 0 0 1 -643 1 2 2.1000000000000001e+00 5.1093691499196279e+00 3.0344492198805675e+00 -6.4345454488330747e+00 0 0 1 -644 1 3 -1.0500000000000000e+00 4.8885491946230193e+00 1.5053074909905106e-01 -8.0605607952707210e+00 0 0 1 -645 1 3 -1.0500000000000000e+00 5.2442304737788277e+00 2.9415916314514909e+00 -8.0593380345474710e+00 0 0 1 -646 1 4 -9.4999999999999996e-01 2.6034643508351554e+00 1.7450925686198282e+00 -8.1894376464302248e+00 0 0 1 -647 1 3 -1.0500000000000000e+00 1.2541470718188243e+00 3.7373860894973312e+00 -5.9607452583898279e+00 0 0 1 -648 1 3 -1.0500000000000000e+00 4.9969207263007007e+00 1.5601142565135646e+00 -5.9585218264668987e+00 0 0 1 -649 1 3 -1.0500000000000000e+00 3.8438755039647781e+00 3.8862509178542481e+00 -6.1504948520704428e+00 0 0 1 -650 1 5 4.2499999999999999e-01 2.0966482421124439e+00 8.6619230423949745e-01 -8.0458138215952246e+00 0 0 1 -651 1 1 1.5750000000000000e+00 3.5115249226044547e+00 5.7907198259501094e+00 9.1936366323746803e+00 0 0 0 -652 1 2 2.1000000000000001e+00 2.4778454716609737e+00 4.5623765389962720e+00 -6.4424549548316898e+00 0 0 1 -653 1 2 2.1000000000000001e+00 2.5575452318876177e+00 7.5173355195879559e+00 -6.4345507119283667e+00 0 0 1 -654 1 3 -1.0500000000000000e+00 2.3366926892607953e+00 4.6334235989140211e+00 -8.0605346523744945e+00 0 0 1 -655 1 3 -1.0500000000000000e+00 2.6924249011193702e+00 7.4244757851521115e+00 -8.0593551007001238e+00 0 0 1 -656 1 4 -9.4999999999999996e-01 5.2116431506887224e+00 6.2279831418827243e+00 -8.1894281256506112e+00 0 0 1 -657 1 3 -1.0500000000000000e+00 3.8623413621431926e+00 8.2202867834463831e+00 -5.9607238698675804e+00 0 0 1 -658 1 3 -1.0500000000000000e+00 2.4450836082692842e+00 6.0430517989917192e+00 -5.9585244820905769e+00 0 0 1 -659 1 3 -1.0500000000000000e+00 1.2920637940504047e+00 8.3691881497510039e+00 -6.1505119182298955e+00 0 0 1 -660 1 5 4.2499999999999999e-01 4.7048138321703057e+00 5.3491559689970316e+00 -8.0457833629094804e+00 0 0 1 -661 1 1 1.5750000000000000e+00 9.1931369634479232e-01 7.2945178217424740e+00 9.1931417040695678e+00 0 0 0 -662 1 2 2.1000000000000001e+00 1.3055260744466146e-01 -7.9317832940208888e-02 6.4359827901812103e+00 0 0 0 -663 1 2 2.1000000000000001e+00 1.0720282113932278e-01 5.9315023318302593e+00 6.4281033508112593e+00 0 0 0 -664 1 3 -1.0500000000000000e+00 3.2788484861811895e-01 8.8153153359292737e+00 8.0541188453755055e+00 0 0 0 -665 1 3 -1.0500000000000000e+00 -2.7640674620188932e-02 6.0245489236297125e+00 8.0528333235673948e+00 0 0 0 -666 1 4 -9.4999999999999996e-01 2.6130074984934222e+00 7.2207811174121979e+00 8.1829820095982306e+00 0 0 0 -667 1 3 -1.0500000000000000e+00 3.9624293928668664e+00 5.2286348819770652e+00 5.9541296325020454e+00 0 0 0 -668 1 3 -1.0500000000000000e+00 2.1947489538717235e-01 7.4058677579145495e+00 5.9521806813040818e+00 0 0 0 -669 1 3 -1.0500000000000000e+00 1.3727195076908174e+00 5.0797829004802750e+00 6.1440221439199547e+00 0 0 0 -670 1 5 4.2499999999999999e-01 3.1199198882547670e+00 8.0998190292999972e+00 8.0392233868226413e+00 0 0 0 -671 1 1 1.5750000000000000e+00 -1.6888477418401209e+00 2.8115771228301263e+00 9.1931465065192413e+00 0 0 0 -672 1 2 2.1000000000000001e+00 2.7387214381664506e+00 4.4035965911325441e+00 6.4359840218950986e+00 0 0 0 -673 1 2 2.1000000000000001e+00 2.6590152039811183e+00 1.4486276554920678e+00 6.4281038900502772e+00 0 0 0 -674 1 3 -1.0500000000000000e+00 2.8797333442489403e+00 4.3324271463750499e+00 8.0541142270027564e+00 0 0 0 -675 1 3 -1.0500000000000000e+00 2.5241681856617681e+00 1.5416551423726865e+00 8.0528437084568978e+00 0 0 0 -676 1 4 -9.4999999999999996e-01 4.8093911077735640e-03 2.7378705543423152e+00 8.1829616488490657e+00 0 0 0 -677 1 3 -1.0500000000000000e+00 1.3542091391053663e+00 7.4571708670846704e-01 5.9541146881430809e+00 0 0 0 -678 1 3 -1.0500000000000000e+00 2.7713119531196178e+00 2.9229176474043648e+00 5.9521714421746275e+00 0 0 0 -679 1 3 -1.0500000000000000e+00 3.9245431086601634e+00 5.9683913538635736e-01 6.1440383200472155e+00 0 0 0 -680 1 5 4.2499999999999999e-01 5.1173590247430134e-01 3.6168514770869997e+00 8.0391067933291254e+00 0 0 0 -681 1 1 1.5750000000000000e+00 6.0633644979866617e+00 1.3077764402381860e+00 9.1936424301437327e+00 0 0 0 -682 1 2 2.1000000000000001e+00 -1.0393956091887130e+01 9.0452986204580199e+00 -6.4424706383653128e+00 1 0 1 -683 1 2 2.1000000000000001e+00 -1.0370639000521159e+01 3.0344401437907607e+00 -6.4345382115271370e+00 1 0 1 -684 1 3 -1.0500000000000000e+00 1.0048533308437719e+01 1.5052907679099903e-01 -8.0605479455575875e+00 0 0 1 -685 1 3 -1.0500000000000000e+00 -1.0235764829535407e+01 2.9415946024168882e+00 -8.0593448738947711e+00 1 0 1 -686 1 4 -9.4999999999999996e-01 7.7634385482822665e+00 1.7450613214128445e+00 -8.1894553026732630e+00 0 0 1 -687 1 3 -1.0500000000000000e+00 6.4141199266752125e+00 3.7373691756750844e+00 -5.9607400003245488e+00 0 0 1 -688 1 3 -1.0500000000000000e+00 -1.0483082992907299e+01 1.5601135575085152e+00 -5.9585049167664010e+00 1 0 1 -689 1 3 -1.0500000000000000e+00 9.0038591861234316e+00 3.8862624469508731e+00 -6.1504976913058753e+00 0 0 1 -690 1 5 4.2499999999999999e-01 7.2566281282265024e+00 8.6617229370341420e-01 -8.0459562616122788e+00 0 0 1 -691 1 1 1.5750000000000000e+00 -1.1968466710883613e+01 5.7907200272594253e+00 9.1936379108217210e+00 1 0 0 -692 1 2 2.1000000000000001e+00 7.6378680747979217e+00 4.5623676359245415e+00 -6.4424554418645830e+00 0 0 1 -693 1 2 2.1000000000000001e+00 7.7175561236862720e+00 7.5173258354996513e+00 -6.4345458370457891e+00 0 0 1 -694 1 3 -1.0500000000000000e+00 7.4966971095246784e+00 4.6334217217216107e+00 -8.0605511418516578e+00 0 0 1 -695 1 3 -1.0500000000000000e+00 7.8524206188978773e+00 7.4244848641613252e+00 -8.0593478379502788e+00 0 0 1 -696 1 4 -9.4999999999999996e-01 -1.0268350840910548e+01 6.2279978436836103e+00 -8.1894126273817580e+00 1 0 1 -697 1 3 -1.0500000000000000e+00 9.0223185487234865e+00 8.2202683987681517e+00 -5.9607306481678064e+00 0 0 1 -698 1 3 -1.0500000000000000e+00 7.6050847030704887e+00 6.0430679157690967e+00 -5.9585183337410061e+00 0 0 1 -699 1 3 -1.0500000000000000e+00 6.4520501689392091e+00 8.3691934430963606e+00 -6.1505097191785891e+00 0 0 1 -700 1 5 4.2499999999999999e-01 9.8648361525616011e+00 5.3491684752263104e+00 -8.0456734689964478e+00 0 0 1 -701 1 1 1.5750000000000000e+00 6.0793231314687830e+00 7.2945172203253925e+00 9.1931433628689199e+00 0 0 0 -702 1 2 2.1000000000000001e+00 5.2905310133240171e+00 -7.9308613989582000e-02 6.4359821727091351e+00 0 0 0 -703 1 2 2.1000000000000001e+00 5.2671909211636532e+00 5.9315118083683132e+00 6.4280991413518187e+00 0 0 0 -704 1 3 -1.0500000000000000e+00 5.4878786119536880e+00 8.8153176389221777e+00 8.0541369285311823e+00 0 0 0 -705 1 3 -1.0500000000000000e+00 5.1323639620923132e+00 6.0245391240881929e+00 8.0528260225861459e+00 0 0 0 -706 1 4 -9.4999999999999996e-01 -1.2866988747643051e+01 7.2207925976713057e+00 8.1829956582926116e+00 1 0 0 -707 1 3 -1.0500000000000000e+00 -1.1517595758277714e+01 5.2286152308444116e+00 5.9541235660469205e+00 1 0 0 -708 1 3 -1.0500000000000000e+00 5.3794735676534788e+00 7.4058518283359085e+00 5.9521757498067629e+00 0 0 0 -709 1 3 -1.0500000000000000e+00 6.5327308131030897e+00 5.0797788531472143e+00 6.1440196202405239e+00 0 0 0 -710 1 5 4.2499999999999999e-01 -1.2360060468950346e+01 8.0998299155301758e+00 8.0393187802592365e+00 1 0 0 -711 1 1 1.5750000000000000e+00 3.4711395835312722e+00 2.8115854873277328e+00 9.1931412782814164e+00 0 0 0 -712 1 2 2.1000000000000001e+00 -1.2741270213355396e+01 4.4036072094345613e+00 6.4359692872070209e+00 1 0 0 -713 1 2 2.1000000000000001e+00 -1.2820992144383402e+01 1.4486168840401561e+00 6.4281117848769433e+00 1 0 0 -714 1 3 -1.0500000000000000e+00 -1.2600282272306931e+01 4.3324249483168984e+00 8.0541252195822324e+00 1 0 0 -715 1 3 -1.0500000000000000e+00 -1.2955827208223699e+01 1.5416588276190986e+00 8.0528375088075776e+00 1 0 0 -716 1 4 -9.4999999999999996e-01 5.1648353667199540e+00 2.7379028672499786e+00 8.1829814227555033e+00 0 0 0 -717 1 3 -1.0500000000000000e+00 6.5142323478177531e+00 7.4573129982167075e-01 5.9541084366239083e+00 0 0 0 -718 1 3 -1.0500000000000000e+00 -1.2708691390490614e+01 2.9229188096781158e+00 5.9521891051144138e+00 1 0 0 -719 1 3 -1.0500000000000000e+00 -1.1555474224032176e+01 5.9685115823068102e-01 6.1440360907645655e+00 1 0 0 -720 1 5 4.2499999999999999e-01 5.6717580888070920e+00 3.6168743721620338e+00 8.0392615934625482e+00 0 0 0 -721 1 1 1.5750000000000000e+00 -9.4166482246551979e+00 1.3077849936001620e+00 9.1936370721707412e+00 1 0 0 -722 1 2 2.1000000000000001e+00 -5.2339619386026222e+00 9.0452876070924795e+00 -6.4424552881548021e+00 1 0 1 -723 1 2 2.1000000000000001e+00 -5.2106301445623524e+00 3.0344497383972460e+00 -6.4345453239074235e+00 1 0 1 -724 1 3 -1.0500000000000000e+00 -5.4314509832052806e+00 1.5053103177049465e-01 -8.0605605145316623e+00 1 0 1 -725 1 3 -1.0500000000000000e+00 -5.0757700467777660e+00 2.9415914134557468e+00 -8.0593381978713854e+00 1 0 1 -726 1 4 -9.4999999999999996e-01 -7.7165352408768761e+00 1.7450926395253603e+00 -8.1894375536125779e+00 1 0 1 -727 1 3 -1.0500000000000000e+00 -9.0658539420445514e+00 3.7373856629968962e+00 -5.9607453508186268e+00 1 0 1 -728 1 3 -1.0500000000000000e+00 -5.3230797573551945e+00 1.5601136771291060e+00 -5.9585224249910560e+00 1 0 1 -729 1 3 -1.0500000000000000e+00 -6.4761243113141163e+00 3.8862506583169747e+00 -6.1504951201005635e+00 1 0 1 -730 1 5 4.2499999999999999e-01 -8.2233515316346129e+00 8.6619249488343186e-01 -8.0458128960845610e+00 1 0 1 -731 1 1 1.5750000000000000e+00 -6.8084749278572794e+00 5.7907199181714617e+00 9.1936368014835779e+00 1 0 0 -732 1 2 2.1000000000000001e+00 -7.8421543543219876e+00 4.5623760988630977e+00 -6.4424551724803507e+00 1 0 1 -733 1 2 2.1000000000000001e+00 -7.7624550474019687e+00 7.5173357600750919e+00 -6.4345507666231665e+00 1 0 1 -734 1 3 -1.0500000000000000e+00 -7.9833072576094679e+00 4.6334236189412472e+00 -8.0605345439778535e+00 1 0 1 -735 1 3 -1.0500000000000000e+00 -7.6275749709860658e+00 7.4244756246856021e+00 -8.0593549858547036e+00 1 0 1 -736 1 4 -9.4999999999999996e-01 -5.1083571265557088e+00 6.2279832324626838e+00 -8.1894281516468350e+00 1 0 1 -737 1 3 -1.0500000000000000e+00 -6.4576583082768408e+00 8.2202871146935550e+00 -5.9607243744715985e+00 1 0 1 -738 1 3 -1.0500000000000000e+00 -7.8749164209304432e+00 6.0430523694022220e+00 -5.9585244932054433e+00 1 0 1 -739 1 3 -1.0500000000000000e+00 -9.0279365094229576e+00 8.3691879113196173e+00 -6.1505119087316054e+00 1 0 1 -740 1 5 4.2499999999999999e-01 -5.6151859285126591e+00 5.3491562088575435e+00 -8.0457831465411420e+00 1 0 1 -741 1 1 1.5750000000000000e+00 -9.4006861228143777e+00 7.2945178641200243e+00 9.1931413587158737e+00 1 0 0 -742 1 2 2.1000000000000001e+00 -1.0189446901732101e+01 -7.9318236792463637e-02 6.4359827880671165e+00 1 0 0 -743 1 2 2.1000000000000001e+00 -1.0212797209504219e+01 5.9315027005656376e+00 6.4281032069197401e+00 1 0 0 -744 1 3 -1.0500000000000000e+00 -9.9921152160719053e+00 8.8153156720518915e+00 8.0541192347406820e+00 1 0 0 -745 1 3 -1.0500000000000000e+00 -1.0347640875111864e+01 6.0245485223092068e+00 8.0528333924487754e+00 1 0 0 -746 1 4 -9.4999999999999996e-01 -7.7069926785168414e+00 7.2207804428448661e+00 8.1829816910360762e+00 1 0 0 -747 1 3 -1.0500000000000000e+00 -6.3575703334558895e+00 5.2286351971224256e+00 5.9541296996752653e+00 1 0 0 -748 1 3 -1.0500000000000000e+00 -1.0100525252458381e+01 7.4058673881614858e+00 5.9521800333630281e+00 1 0 0 -749 1 3 -1.0500000000000000e+00 -8.9472807033657631e+00 5.0797825189783623e+00 6.1440221907007029e+00 1 0 0 -750 1 5 4.2499999999999999e-01 -7.2000802231122059e+00 8.0998189309149993e+00 8.0392211665542135e+00 1 0 0 -751 1 1 1.5750000000000000e+00 -1.2008847797524796e+01 2.8115770829703060e+00 9.1931467114672394e+00 1 0 0 -752 1 2 2.1000000000000001e+00 -7.5812787302564342e+00 4.4035969903177126e+00 6.4359840736895855e+00 1 0 0 -753 1 2 2.1000000000000001e+00 -7.6609845142731885e+00 1.4486270707354976e+00 6.4281037714129887e+00 1 0 0 -754 1 3 -1.0500000000000000e+00 -7.4402667238785334e+00 4.3324268554054939e+00 8.0541134191189272e+00 1 0 0 -755 1 3 -1.0500000000000000e+00 -7.7958321260701204e+00 1.5416555458757131e+00 8.0528432400587633e+00 1 0 0 -756 1 4 -9.4999999999999996e-01 -1.0315190869488516e+01 2.7378699638266895e+00 8.1829614726589632e+00 1 0 0 -757 1 3 -1.0500000000000000e+00 -8.9657915597118514e+00 7.4571717134691085e-01 5.9541148264232131e+00 1 0 0 -758 1 3 -1.0500000000000000e+00 -7.5486882096211598e+00 2.9229181158770956e+00 5.9521717592426171e+00 1 0 0 -759 1 3 -1.0500000000000000e+00 -6.3954568056499070e+00 5.9683881964126329e-01 6.1440384017210938e+00 1 0 0 -760 1 5 4.2499999999999999e-01 -9.8082640370540322e+00 3.6168517326208622e+00 8.0391061668832791e+00 1 0 0 -761 1 1 1.5750000000000000e+00 -4.2566352159178011e+00 1.3077765305086579e+00 9.1936420772794243e+00 1 0 0 -762 1 2 2.1000000000000001e+00 -7.3955702905495357e-02 9.0452984397155127e+00 -6.4424705112255527e+00 1 0 1 -763 1 2 2.1000000000000001e+00 -5.0639268804218318e-02 3.0344401838555015e+00 -6.4345380811994373e+00 1 0 1 -764 1 3 -1.0500000000000000e+00 -2.7146671876940864e-01 1.5052948229473628e-01 -8.0605477372777710e+00 1 0 1 -765 1 3 -1.0500000000000000e+00 8.4234987628711622e-02 2.9415941872048172e+00 -8.0593450341223907e+00 1 0 1 -766 1 4 -9.4999999999999996e-01 -2.5565617900078745e+00 1.7450602668030974e+00 -8.1894558875563099e+00 1 0 1 -767 1 3 -1.0500000000000000e+00 -3.9058798496030818e+00 3.7373693975026470e+00 -5.9607397640875526e+00 1 0 1 -768 1 3 -1.0500000000000000e+00 -1.6308309853130609e-01 1.5601131606355310e+00 -5.9585056499379956e+00 1 0 1 -769 1 3 -1.0500000000000000e+00 -1.3161409487212250e+00 3.8862620885601835e+00 -6.1504976924599708e+00 1 0 1 -770 1 5 4.2499999999999999e-01 -3.0633721304777737e+00 8.6617180932852378e-01 -8.0459600673758906e+00 1 0 1 -771 1 1 1.5750000000000000e+00 -1.6484667402492086e+00 5.7907199963413696e+00 9.1936380439006840e+00 1 0 0 -772 1 2 2.1000000000000001e+00 -2.6821319233270762e+00 4.5623678924352262e+00 -6.4424555850302845e+00 1 0 1 -773 1 2 2.1000000000000001e+00 -2.6024436522515684e+00 7.5173249865978811e+00 -6.4345459794676945e+00 1 0 1 -774 1 3 -1.0500000000000000e+00 -2.8233029553519291e+00 4.6334213067591676e+00 -8.0605518736723774e+00 1 0 1 -775 1 3 -1.0500000000000000e+00 -2.4675796682151825e+00 7.4244854436344596e+00 -8.0593482859729608e+00 1 0 1 -776 1 4 -9.4999999999999996e-01 5.1649080036435535e-02 6.2279974849230868e+00 -8.1894126171390074e+00 1 0 1 -777 1 3 -1.0500000000000000e+00 -1.2976821039686737e+00 8.2202684684538738e+00 -5.9607304730846167e+00 1 0 1 -778 1 3 -1.0500000000000000e+00 -2.7149155839124708e+00 6.0430686029330261e+00 -5.9585178379165145e+00 1 0 1 -779 1 3 -1.0500000000000000e+00 -3.8679498876990923e+00 8.3691932428860518e+00 -6.1505097411913079e+00 1 0 1 -780 1 5 4.2499999999999999e-01 -4.5516375461291148e-01 5.3491689410228709e+00 -8.0456731276029334e+00 1 0 1 -781 1 1 1.5750000000000000e+00 -4.2406767104337693e+00 7.2945170235932544e+00 9.1931432914057254e+00 1 0 0 -782 1 2 2.1000000000000001e+00 -5.0294679817969996e+00 -7.9308383266852189e-02 6.4359820907808079e+00 1 0 0 -783 1 2 2.1000000000000001e+00 -5.0528084095329788e+00 5.9315121765530456e+00 6.4280993177329151e+00 1 0 0 -784 1 3 -1.0500000000000000e+00 -4.8321216884293952e+00 8.8153178102125764e+00 8.0541373333119068e+00 1 0 0 -785 1 3 -1.0500000000000000e+00 -5.1876365042459005e+00 6.0245390204362508e+00 8.0528256846894841e+00 1 0 0 -786 1 4 -9.4999999999999996e-01 -2.5469883283675090e+00 7.2207929231726879e+00 8.1829957473941626e+00 1 0 0 -787 1 3 -1.0500000000000000e+00 -1.1975963260808307e+00 5.2286152114606139e+00 5.9541233899506381e+00 1 0 0 -788 1 3 -1.0500000000000000e+00 -4.9405269747949454e+00 7.4058516691213789e+00 5.9521754240417550e+00 1 0 0 -789 1 3 -1.0500000000000000e+00 -3.7872688367566179e+00 5.0797787478627363e+00 6.1440193033359680e+00 1 0 0 -790 1 5 4.2499999999999999e-01 -2.0400603579454231e+00 8.0998301275343039e+00 8.0393199026612976e+00 1 0 0 -791 1 1 1.5750000000000000e+00 -6.8488602476836844e+00 2.8115856871897833e+00 9.1931414513231040e+00 1 0 0 -792 1 2 2.1000000000000001e+00 -2.4212702997666087e+00 4.4036064510741433e+00 6.4359692474571553e+00 1 0 0 -793 1 2 2.1000000000000001e+00 -2.5009926008971028e+00 1.4486174252197621e+00 6.4281116373570182e+00 1 0 0 -794 1 3 -1.0500000000000000e+00 -2.2802823629707447e+00 4.3324251847658566e+00 8.0541253999526816e+00 1 0 0 -795 1 3 -1.0500000000000000e+00 -2.6358272967366059e+00 1.5416586904290384e+00 8.0528378116446149e+00 1 0 0 -796 1 4 -9.4999999999999996e-01 -5.1551643554524418e+00 2.7379037608809824e+00 8.1829814672982195e+00 1 0 0 -797 1 3 -1.0500000000000000e+00 -3.8057673790650339e+00 7.4573157826670666e-01 5.9541081971998757e+00 1 0 0 -798 1 3 -1.0500000000000000e+00 -2.3886914872172689e+00 2.9229192871494014e+00 5.9521889727847714e+00 1 0 0 -799 1 3 -1.0500000000000000e+00 -1.2354742749578769e+00 5.9685082984797688e-01 6.1440360206027229e+00 1 0 0 -800 1 5 4.2499999999999999e-01 -4.6482418197172777e+00 3.6168744710139755e+00 8.0392633370875117e+00 1 0 0 -801 1 1 1.5750000000000000e+00 9.5967873870649711e-01 1.0273627931332530e+01 9.1936332543784474e+00 0 0 0 -802 1 2 2.1000000000000001e+00 4.9170202879792217e+00 -1.7852197301472376e+01 -6.4424472392317949e+00 0 1 1 -803 1 2 2.1000000000000001e+00 5.1657083021387304e+00 1.2000270148268925e+01 -6.4345416661062043e+00 0 0 1 -804 1 3 -1.0500000000000000e+00 4.9448718486394441e+00 9.1163592509260383e+00 -8.0605453318814781e+00 0 0 1 -805 1 3 -1.0500000000000000e+00 5.3005686505046405e+00 1.1907407924582206e+01 -8.0593391691285294e+00 0 0 1 -806 1 4 -9.4999999999999996e-01 2.6598377775423838e+00 1.0710974732920558e+01 -8.1893913942181342e+00 0 0 1 -807 1 3 -1.0500000000000000e+00 1.3104907237727232e+00 1.2703204121362479e+01 -5.9607442567543920e+00 0 0 1 -808 1 3 -1.0500000000000000e+00 5.0532627057093062e+00 1.0525966373485492e+01 -5.9585521960462655e+00 0 0 1 -809 1 3 -1.0500000000000000e+00 3.9002095894378765e+00 1.2852072048143445e+01 -6.1504923711143187e+00 0 0 1 -810 1 5 4.2499999999999999e-01 2.1530086079626720e+00 9.8321167566669843e+00 -8.0454591961221276e+00 0 0 1 -811 1 1 1.5750000000000000e+00 3.5678604499193511e+00 1.4756518660337544e+01 9.1936395263569040e+00 0 0 0 -812 1 2 2.1000000000000001e+00 2.5341877928951977e+00 1.3528224919927343e+01 -6.4424657239495549e+00 0 0 1 -813 1 2 2.1000000000000001e+00 2.6138676090779143e+00 1.6483174950079718e+01 -6.4345483081542341e+00 0 0 1 -814 1 3 -1.0500000000000000e+00 2.3930402058650380e+00 1.3599255594666559e+01 -8.0605475895669922e+00 0 0 1 -815 1 3 -1.0500000000000000e+00 2.7487447696605347e+00 1.6390315618000596e+01 -8.0593484931625419e+00 0 0 1 -816 1 4 -9.4999999999999996e-01 5.2679459006484635e+00 1.5193780993781782e+01 -8.1894623271280569e+00 0 0 1 -817 1 3 -1.0500000000000000e+00 3.9186548010514208e+00 1.7186118080045279e+01 -5.9607338497847966e+00 0 0 1 -818 1 3 -1.0500000000000000e+00 2.5014167434283738e+00 1.5008842532834354e+01 -5.9585074223694736e+00 0 0 1 -819 1 3 -1.0500000000000000e+00 1.3483851372911495e+00 1.7334998612866539e+01 -6.1505045920395949e+00 0 0 1 -820 1 5 4.2499999999999999e-01 4.7611267101014434e+00 1.4314896916392993e+01 -8.0460208685809498e+00 0 0 1 -821 1 1 1.5750000000000000e+00 9.7564154508196665e-01 1.6260329204368485e+01 9.1931413861510229e+00 0 0 0 -822 1 2 2.1000000000000001e+00 1.8688751365847622e-01 8.8864831418917092e+00 6.4359900505714904e+00 0 0 0 -823 1 2 2.1000000000000001e+00 1.6352477848671398e-01 1.4897345335858450e+01 6.4281099691348906e+00 0 0 0 -824 1 3 -1.0500000000000000e+00 1.5888466591680483e-01 -1.8082135489320500e+01 8.0541187400884375e+00 0 1 0 -825 1 3 -1.0500000000000000e+00 2.8676845698212716e-02 1.4990388505335250e+01 8.0528413813741047e+00 0 0 0 -826 1 4 -9.4999999999999996e-01 2.6693415045844695e+00 1.6186635340657890e+01 8.1829863297743231e+00 0 0 0 -827 1 3 -1.0500000000000000e+00 4.0187451606434799e+00 1.4194464566085703e+01 5.9541180271056255e+00 0 0 0 -828 1 3 -1.0500000000000000e+00 2.7581495837045722e-01 1.6371678680141809e+01 5.9521706277716682e+00 0 0 0 -829 1 3 -1.0500000000000000e+00 1.4290361400725828e+00 1.4045585958963279e+01 6.1440356652053030e+00 0 0 0 -830 1 5 4.2499999999999999e-01 3.1762525265139896e+00 1.7065643300229763e+01 8.0392944572772080e+00 0 0 0 -831 1 1 1.5750000000000000e+00 -1.6325037604360304e+00 1.1777393054005071e+01 9.1931494380911758e+00 0 0 0 -832 1 2 2.1000000000000001e+00 2.7950463050835612e+00 1.3369426562471293e+01 6.4359848929528098e+00 0 0 0 -833 1 2 2.1000000000000001e+00 2.7153546369087991e+00 1.0414440225986954e+01 6.4280970948715428e+00 0 0 0 -834 1 3 -1.0500000000000000e+00 2.9360741185949557e+00 1.3298235729980501e+01 8.0541031634140268e+00 0 0 0 -835 1 3 -1.0500000000000000e+00 2.5805102175501133e+00 1.0507472480710458e+01 8.0528403633425008e+00 0 0 0 -836 1 4 -9.4999999999999996e-01 6.1116261018881346e-02 1.1703631646208919e+01 8.1829255323196435e+00 0 0 0 -837 1 3 -1.0500000000000000e+00 1.4105482236895384e+00 9.7115390002741222e+00 5.9541218211882700e+00 0 0 0 -838 1 3 -1.0500000000000000e+00 2.8276383267741920e+00 1.1888727192262071e+01 5.9521988254711484e+00 0 0 0 -839 1 3 -1.0500000000000000e+00 3.9808889192955643e+00 9.5626751238088765e+00 6.1440287506276636e+00 0 0 0 -840 1 5 4.2499999999999999e-01 5.6805237294861577e-01 1.2582600671306029e+01 8.0388069430812692e+00 0 0 0 -841 1 1 1.5750000000000000e+00 6.1196916481461798e+00 1.0273619311595212e+01 9.1936385701976455e+00 0 0 0 -842 1 2 2.1000000000000001e+00 -1.0562972967868294e+01 -1.7852186124582051e+01 -6.4424618866493581e+00 1 1 1 -843 1 2 2.1000000000000001e+00 -1.0314300463088895e+01 1.2000260817155858e+01 -6.4345343147472276e+00 1 0 1 -844 1 3 -1.0500000000000000e+00 1.0104855998898849e+01 9.1163573147114043e+00 -8.0605322725826341e+00 0 0 1 -845 1 3 -1.0500000000000000e+00 -1.0179427041092397e+01 1.1907410707444317e+01 -8.0593460937248125e+00 1 0 1 -846 1 4 -9.4999999999999996e-01 7.8198121743855253e+00 1.0710943621470591e+01 -8.1894089539912898e+00 0 0 1 -847 1 3 -1.0500000000000000e+00 6.4704637356426886e+00 1.2703187622578351e+01 -5.9607389666874369e+00 0 0 1 -848 1 3 -1.0500000000000000e+00 -1.0426741160580578e+01 1.0525965677574206e+01 -5.9585352050258882e+00 1 0 1 -849 1 3 -1.0500000000000000e+00 9.0601938982153492e+00 1.2852082973415254e+01 -6.1504952513789970e+00 0 0 1 -850 1 5 4.2499999999999999e-01 7.3129890415569641e+00 9.8320975601586795e+00 -8.0455995221888763e+00 0 0 1 -851 1 1 1.5750000000000000e+00 -1.1912131115243776e+01 1.4756518511630393e+01 9.1936409031930566e+00 1 0 0 -852 1 2 2.1000000000000001e+00 7.6942103515588727e+00 1.3528216084532719e+01 -6.4424660656676469e+00 0 0 1 -853 1 2 2.1000000000000001e+00 7.7738783974448822e+00 1.6483164932356882e+01 -6.4345438123469325e+00 0 0 1 -854 1 3 -1.0500000000000000e+00 7.5530450745468620e+00 1.3599253594074110e+01 -8.0605645707773075e+00 0 0 1 -855 1 3 -1.0500000000000000e+00 7.9087406576636390e+00 1.6390325011984924e+01 -8.0593415508830937e+00 0 0 1 -856 1 4 -9.4999999999999996e-01 -1.0212048060240685e+01 1.5193795439600176e+01 -8.1894472903213646e+00 1 0 1 -857 1 3 -1.0500000000000000e+00 9.0786324641144454e+00 1.7186100136982798e+01 -5.9607404476388419e+00 0 0 1 -858 1 3 -1.0500000000000000e+00 7.6614176755073657e+00 1.5008858795686283e+01 -5.9585014790141466e+00 0 0 1 -859 1 3 -1.0500000000000000e+00 6.5083717980655358e+00 1.7335003785043835e+01 -6.1505020964091477e+00 0 0 1 -860 1 5 4.2499999999999999e-01 9.9211482380772580e+00 1.4314908930826856e+01 -8.0459136811606840e+00 0 0 1 -861 1 1 1.5750000000000000e+00 6.1356506663376074e+00 1.6260328799586329e+01 9.1931428054091135e+00 0 0 0 -862 1 2 2.1000000000000001e+00 5.3468660465751885e+00 8.8864925886850372e+00 6.4359890819195265e+00 0 0 0 -863 1 2 2.1000000000000001e+00 5.3235129414199207e+00 1.4897354902312319e+01 6.4281056165222665e+00 0 0 0 -864 1 3 -1.0500000000000000e+00 5.3188786678135589e+00 -1.8082133570570267e+01 8.0541365045086479e+00 0 1 0 -865 1 3 -1.0500000000000000e+00 5.1886815368271826e+00 1.4990379033530626e+01 8.0528335644133122e+00 0 0 0 -866 1 4 -9.4999999999999996e-01 -1.2810654584859369e+01 1.6186646896184879e+01 8.1830000399083929e+00 1 0 0 -867 1 3 -1.0500000000000000e+00 -1.1461280205702918e+01 1.4194444824933296e+01 5.9541121816292097e+00 1 0 0 -868 1 3 -1.0500000000000000e+00 5.4358135861863435e+00 1.6371662225791912e+01 5.9521656290902456e+00 0 0 0 -869 1 3 -1.0500000000000000e+00 6.5890471641883330e+00 1.4045582047251091e+01 6.1440334261248104e+00 0 0 0 -870 1 5 4.2499999999999999e-01 -1.2303727462568279e+01 1.7065653619940949e+01 8.0393893441723741e+00 1 0 0 -871 1 1 1.5750000000000000e+00 3.5274838259832713e+00 1.1777401493280070e+01 9.1931441416147273e+00 0 0 0 -872 1 2 2.1000000000000001e+00 -1.2684944822449953e+01 1.3369436728804907e+01 6.4359697826941868e+00 1 0 0 -873 1 2 2.1000000000000001e+00 -1.2764652935221005e+01 1.0414429351817827e+01 6.4281050888226883e+00 1 0 0 -874 1 3 -1.0500000000000000e+00 -1.2543941289441408e+01 1.3298233706024533e+01 8.0541143424640254e+00 1 0 0 -875 1 3 -1.0500000000000000e+00 -1.2899485650730099e+01 1.0507476104116062e+01 8.0528342665717290e+00 1 0 0 -876 1 4 -9.4999999999999996e-01 5.2211420536049840e+00 1.1703663571348297e+01 8.1829446657261684e+00 0 0 0 -877 1 3 -1.0500000000000000e+00 6.5705712794450086e+00 9.7115531350575814e+00 5.9541154368520921e+00 0 0 0 -878 1 3 -1.0500000000000000e+00 -1.2652365228052556e+01 1.1888728577809754e+01 5.9522163248080702e+00 1 0 0 -879 1 3 -1.0500000000000000e+00 -1.1499128222193754e+01 9.5626868373927500e+00 6.1440263154948518e+00 1 0 0 -880 1 5 4.2499999999999999e-01 5.7280739035960409e+00 1.2582622309869635e+01 8.0389576983163877e+00 0 0 0 -881 1 1 1.5750000000000000e+00 -9.3603210300233410e+00 1.0273627849279887e+01 9.1936330635970158e+00 1 0 0 -882 1 2 2.1000000000000001e+00 -5.4029789250223814e+00 -1.7852196908435001e+01 -6.4424469172394012e+00 1 1 1 -883 1 2 2.1000000000000001e+00 -5.1542911291229290e+00 1.2000270474496883e+01 -6.4345417150059125e+00 1 0 1 -884 1 3 -1.0500000000000000e+00 -5.3751285666616679e+00 9.1163593033370276e+00 -8.0605448619571209e+00 1 0 1 -885 1 3 -1.0500000000000000e+00 -5.0194319464843193e+00 1.1907407649964579e+01 -8.0593393447723809e+00 1 0 1 -886 1 4 -9.4999999999999996e-01 -7.6601619903871123e+00 1.0710974524748739e+01 -8.1893914371122047e+00 1 0 1 -887 1 3 -1.0500000000000000e+00 -9.0095098129106699e+00 1.2703204080713530e+01 -5.9607445526537255e+00 1 0 1 -888 1 3 -1.0500000000000000e+00 -5.2667379209114200e+00 1.0525965933656611e+01 -5.9585526687735655e+00 1 0 1 -889 1 3 -1.0500000000000000e+00 -6.4197902412194825e+00 1.2852071735735553e+01 -6.1504926191601674e+00 1 0 1 -890 1 5 4.2499999999999999e-01 -8.1669914205476974e+00 9.8321167307240600e+00 -8.0454595936934830e+00 1 0 1 -891 1 1 1.5750000000000000e+00 -6.7521395205583286e+00 1.4756518760999366e+01 9.1936397174990141e+00 1 0 0 -892 1 2 2.1000000000000001e+00 -7.7858122892998054e+00 1.3528224461052016e+01 -6.4424656139275838e+00 1 0 1 -893 1 2 2.1000000000000001e+00 -7.7061325293478093e+00 1.6483175326594630e+01 -6.4345480830706414e+00 1 0 1 -894 1 3 -1.0500000000000000e+00 -7.9269598589484644e+00 1.3599255745258660e+01 -8.0605475744769084e+00 1 0 1 -895 1 3 -1.0500000000000000e+00 -7.5712552979259540e+00 1.6390315489107760e+01 -8.0593486144477531e+00 1 0 1 -896 1 4 -9.4999999999999996e-01 -5.0520542294944786e+00 1.5193781329353431e+01 -8.1894622360343359e+00 1 0 1 -897 1 3 -1.0500000000000000e+00 -6.4013448537715316e+00 1.7186118364059144e+01 -5.9607341514068946e+00 1 0 1 -898 1 3 -1.0500000000000000e+00 -7.8185833546132715e+00 1.5008842854382163e+01 -5.9585076005385744e+00 1 0 1 -899 1 3 -1.0500000000000000e+00 -8.9716150603597615e+00 1.7334998186871498e+01 -6.1505045420039695e+00 1 0 1 -900 1 5 4.2499999999999999e-01 -5.5588731281564199e+00 1.4314897211315742e+01 -8.0460196660694052e+00 1 0 1 -901 1 1 1.5750000000000000e+00 -9.3443582015701789e+00 1.6260329295589830e+01 9.1931411627676205e+00 1 0 0 -902 1 2 2.1000000000000001e+00 -1.0133112213408694e+01 8.8864832365779698e+00 6.4359899998556109e+00 1 0 0 -903 1 2 2.1000000000000001e+00 -1.0156475269930002e+01 1.4897345743184555e+01 6.4281099323153992e+00 1 0 0 -904 1 3 -1.0500000000000000e+00 -1.0161115419702764e+01 -1.8082135374524707e+01 8.0541190488754104e+00 1 1 0 -905 1 3 -1.0500000000000000e+00 -1.0291323474841139e+01 1.4990388234657278e+01 8.0528411632971775e+00 1 0 0 -906 1 4 -9.4999999999999996e-01 -7.6506587819248821e+00 1.6186634661685556e+01 8.1829860857223267e+00 1 0 0 -907 1 3 -1.0500000000000000e+00 -6.3012546090935260e+00 1.4194464769286785e+01 5.9541182632805647e+00 1 0 0 -908 1 3 -1.0500000000000000e+00 -1.0044185420157641e+01 1.6371678354147097e+01 5.9521703334486133e+00 1 0 0 -909 1 3 -1.0500000000000000e+00 -8.8909641595171074e+00 1.4045585729388819e+01 6.1440356473451985e+00 1 0 0 -910 1 5 4.2499999999999999e-01 -7.1437475078366361e+00 1.7065643084204066e+01 8.0392921635998036e+00 1 0 0 -911 1 1 1.5750000000000000e+00 -1.1952503806908329e+01 1.1777392935988885e+01 9.1931494896399037e+00 1 0 0 -912 1 2 2.1000000000000001e+00 -7.5249535540070509e+00 1.3369426706708342e+01 6.4359849229161679e+00 1 0 0 -913 1 2 2.1000000000000001e+00 -7.6046455465927938e+00 1.0414439738714904e+01 6.4280970665423425e+00 1 0 0 -914 1 3 -1.0500000000000000e+00 -7.3839259387757039e+00 1.3298235500629829e+01 8.0541025378527777e+00 1 0 0 -915 1 3 -1.0500000000000000e+00 -7.7394899225422495e+00 1.0507472865262848e+01 8.0528399504904762e+00 1 0 0 -916 1 4 -9.4999999999999996e-01 -1.0258883870348837e+01 1.1703631437502466e+01 8.1829256036821505e+00 1 0 0 -917 1 3 -1.0500000000000000e+00 -8.9094521506888338e+00 9.7115391861544396e+00 5.9541217664035742e+00 1 0 0 -918 1 3 -1.0500000000000000e+00 -7.4923619143403553e+00 1.1888727832630579e+01 5.9521991373997416e+00 1 0 0 -919 1 3 -1.0500000000000000e+00 -6.3391107143627821e+00 9.5626748252562983e+00 6.1440288350572487e+00 1 0 0 -920 1 5 4.2499999999999999e-01 -9.7519474212994410e+00 1.2582601048791904e+01 8.0388075081552657e+00 1 0 0 -921 1 1 1.5750000000000000e+00 -4.2003082385719424e+00 1.0273619380112891e+01 9.1936383041100918e+00 1 0 0 -922 1 2 2.1000000000000001e+00 -2.4297294656988733e-01 -1.7852186311786792e+01 -6.4424616537167854e+00 1 1 1 -923 1 2 2.1000000000000001e+00 5.6992461342204592e-03 1.2000260819764481e+01 -6.4345341715263347e+00 1 0 1 -924 1 3 -1.0500000000000000e+00 -2.1514406503791683e-01 9.1163580293140107e+00 -8.0605320486705363e+00 1 0 1 -925 1 3 -1.0500000000000000e+00 1.4057279654934618e-01 1.1907410166961100e+01 -8.0593458440077033e+00 1 0 1 -926 1 4 -9.4999999999999996e-01 -2.5001879890029999e+00 1.0710942864627402e+01 -8.1894092499414750e+00 1 0 1 -927 1 3 -1.0500000000000000e+00 -3.8495358491069132e+00 1.2703187817599940e+01 -5.9607384873530158e+00 1 0 1 -928 1 3 -1.0500000000000000e+00 -1.0674130418211014e-01 1.0525965709510533e+01 -5.9585360724865559e+00 1 0 1 -929 1 3 -1.0500000000000000e+00 -1.2598064291277034e+00 1.2852082807720773e+01 -6.1504952494366680e+00 1 0 1 -930 1 5 4.2499999999999999e-01 -3.0070111159419923e+00 9.8320973069898692e+00 -8.0456018933295201e+00 1 0 1 -931 1 1 1.5750000000000000e+00 -1.5921312099396996e+00 1.4756518501068431e+01 9.1936410306725875e+00 1 0 0 -932 1 2 2.1000000000000001e+00 -2.6257898369011077e+00 1.3528216472440302e+01 -6.4424659490144265e+00 1 0 1 -933 1 2 2.1000000000000001e+00 -2.5461217809795160e+00 1.6483164449566313e+01 -6.4345438559686441e+00 1 0 1 -934 1 3 -1.0500000000000000e+00 -2.7669548660309733e+00 1.3599253406591824e+01 -8.0605652201832392e+00 1 0 1 -935 1 3 -1.0500000000000000e+00 -2.4112596160501099e+00 1.6390325145311063e+01 -8.0593417379908239e+00 1 0 1 -936 1 4 -9.4999999999999996e-01 1.0795194997298196e-01 1.5193795450143018e+01 -8.1894471812195988e+00 1 0 1 -937 1 3 -1.0500000000000000e+00 -1.2413679691063475e+00 1.7186100118376100e+01 -5.9607401168100020e+00 1 0 1 -938 1 3 -1.0500000000000000e+00 -2.6585824593145011e+00 1.5008859065740243e+01 -5.9585013025468836e+00 1 0 1 -939 1 3 -1.0500000000000000e+00 -3.8116281159514180e+00 1.7335003526964119e+01 -6.1505020763972453e+00 1 0 1 -940 1 5 4.2499999999999999e-01 -3.9885165040097448e-01 1.4314909109039110e+01 -8.0459128290620683e+00 1 0 1 -941 1 1 1.5750000000000000e+00 -4.1843492788429355e+00 1.6260328656623525e+01 9.1931428206723105e+00 1 0 0 -942 1 2 2.1000000000000001e+00 -4.9731337052111106e+00 8.8864925780343569e+00 6.4359891646147140e+00 1 0 0 -943 1 2 2.1000000000000001e+00 -4.9964864821328590e+00 1.4897355096540675e+01 6.4281057047584120e+00 1 0 0 -944 1 3 -1.0500000000000000e+00 -5.0011214630853029e+00 -1.8082133136072240e+01 8.0541366977826208e+00 1 1 0 -945 1 3 -1.0500000000000000e+00 -5.1313189603800895e+00 1.4990378740914405e+01 8.0528336659534148e+00 1 0 0 -946 1 4 -9.4999999999999996e-01 -2.4906543735050963e+00 1.6186647087772688e+01 8.1830002777630284e+00 1 0 0 -947 1 3 -1.0500000000000000e+00 -1.1412808284991325e+00 1.4194444533402208e+01 5.9541118505158508e+00 1 0 0 -948 1 3 -1.0500000000000000e+00 -4.8841869111874239e+00 1.6371662492091328e+01 5.9521651522301759e+00 1 0 0 -949 1 3 -1.0500000000000000e+00 -3.7309525841915132e+00 1.4045581824888934e+01 6.1440332311575858e+00 1 0 0 -950 1 5 4.2499999999999999e-01 -1.9837273555664403e+00 1.7065653931110848e+01 8.0393906345572148e+00 1 0 0 -951 1 1 1.5750000000000000e+00 -6.7925162015894784e+00 1.1777401539875704e+01 9.1931443267852408e+00 1 0 0 -952 1 2 2.1000000000000001e+00 -2.3649450878253377e+00 1.3369436582224647e+01 6.4359697354207945e+00 1 0 0 -953 1 2 2.1000000000000001e+00 -2.4446535624417400e+00 1.0414429986717128e+01 6.4281049210260797e+00 1 0 0 -954 1 3 -1.0500000000000000e+00 -2.2239413115898845e+00 1.3298233768882039e+01 8.0541146140340700e+00 1 0 0 -955 1 3 -1.0500000000000000e+00 -2.5794854638881546e+00 1.0507475905429775e+01 8.0528344847928608e+00 1 0 0 -956 1 4 -9.4999999999999996e-01 -5.0988578381565279e+00 1.1703664202648458e+01 8.1829448344403275e+00 1 0 0 -957 1 3 -1.0500000000000000e+00 -3.7494279185375117e+00 9.7115536442377000e+00 5.9541151720722834e+00 1 0 0 -958 1 3 -1.0500000000000000e+00 -2.3323652023331976e+00 1.1888728549734527e+01 5.9522163462646276e+00 1 0 0 -959 1 3 -1.0500000000000000e+00 -1.1791284408340488e+00 9.5626867394875603e+00 6.1440263355411169e+00 1 0 0 -960 1 5 4.2499999999999999e-01 -4.5919259072198466e+00 1.2582622460164927e+01 8.0389591946748382e+00 1 0 0 -961 1 1 1.5750000000000000e+00 7.9068100191729762e-01 -1.6623826667794933e+01 9.1936329115956497e+00 0 1 0 -962 1 2 2.1000000000000001e+00 4.9733529092218784e+00 -8.8863546322481053e+00 -6.4424530599187833e+00 0 1 1 -963 1 2 2.1000000000000001e+00 4.9967174206878386e+00 -1.4897219081193768e+01 -6.4345485920672800e+00 0 1 1 -964 1 3 -1.0500000000000000e+00 4.7758614771918388e+00 -1.7781128207358101e+01 -8.0605421713963512e+00 0 1 1 -965 1 3 -1.0500000000000000e+00 5.1315823076909783e+00 -1.4990077969933255e+01 -8.0593476476060868e+00 0 1 1 -966 1 4 -9.4999999999999996e-01 2.4908397322397562e+00 -1.6186517843881436e+01 -8.1893892594686388e+00 0 1 1 -967 1 3 -1.0500000000000000e+00 1.1415069070616219e+00 -1.4194272347947962e+01 -5.9607326160155054e+00 0 1 1 -968 1 3 -1.0500000000000000e+00 4.8842538335109111e+00 -1.6371486573434453e+01 -5.9585454747590232e+00 0 1 1 -969 1 3 -1.0500000000000000e+00 3.7312242645620088e+00 -1.4045377384298172e+01 -6.1505058531311780e+00 0 1 1 -970 1 5 4.2499999999999999e-01 1.9840099791553261e+00 -1.7065337944145849e+01 -8.0454784074821095e+00 0 1 1 -971 1 1 1.5750000000000000e+00 3.3988468378336183e+00 -1.2140946816454726e+01 9.1936368201047145e+00 0 1 0 -972 1 2 2.1000000000000001e+00 2.3651946584244730e+00 -1.3369247174496831e+01 -6.4424674035830973e+00 0 1 1 -973 1 2 2.1000000000000001e+00 2.4448569934401601e+00 -1.0414281880079912e+01 -6.4345409289964444e+00 0 1 1 -974 1 3 -1.0500000000000000e+00 2.2240319820515140e+00 -1.3298197221789199e+01 -8.0605385489359040e+00 0 1 1 -975 1 3 -1.0500000000000000e+00 2.5797305569898477e+00 -1.0507146034513388e+01 -8.0593438288422270e+00 0 1 1 -976 1 4 -9.4999999999999996e-01 5.0989648405420134e+00 -1.1703630557563750e+01 -8.1894312166848984e+00 0 1 1 -977 1 3 -1.0500000000000000e+00 3.7496430160258374e+00 -9.7113485371468435e+00 -5.9607413491737375e+00 0 1 1 -978 1 3 -1.0500000000000000e+00 2.3324208249127683e+00 -1.1888617571021193e+01 -5.9585329699657352e+00 0 1 1 -979 1 3 -1.0500000000000000e+00 1.1793683075684740e+00 -9.5624860427313276e+00 -6.1504936011882192e+00 0 1 1 -980 1 5 4.2499999999999999e-01 4.5921372238390479e+00 -1.2582510066844680e+01 -8.0457566278645487e+00 0 1 1 -981 1 1 1.5750000000000000e+00 8.0664379617445903e-01 -1.0637161485826958e+01 9.1931451614592419e+00 0 1 0 -982 1 2 2.1000000000000001e+00 1.7896973241679603e-02 -1.8010973641718170e+01 6.4359817745672014e+00 0 1 0 -983 1 2 2.1000000000000001e+00 -5.4852132571987511e-03 -1.2000118994835145e+01 6.4281073327858902e+00 0 1 0 -984 1 3 -1.0500000000000000e+00 2.1523215787156325e-01 -9.1163145167900623e+00 8.0541027005146546e+00 0 1 0 -985 1 3 -1.0500000000000000e+00 -1.4033371887284574e-01 -1.1907072107303144e+01 8.0528440686079286e+00 0 1 0 -986 1 4 -9.4999999999999996e-01 2.5002982006073271e+00 -1.0710888600791460e+01 8.1829397167441016e+00 0 1 0 -987 1 3 -1.0500000000000000e+00 3.8497286338004812e+00 -1.2702999323809529e+01 5.9541155531840584e+00 0 1 0 -988 1 3 -1.0500000000000000e+00 1.0680473021956161e-01 -1.0525820558593288e+01 5.9521993355673537e+00 0 1 0 -989 1 3 -1.0500000000000000e+00 1.2600292062288716e+00 -1.2851884205000303e+01 6.1440355066544665e+00 0 1 0 -990 1 5 4.2499999999999999e-01 3.0072208175545470e+00 -9.8319303710582702e+00 8.0389403597842701e+00 0 1 0 -991 1 1 1.5750000000000000e+00 -1.8015075298494079e+00 -1.5120052496120376e+01 9.1931468500114342e+00 0 1 0 -992 1 2 2.1000000000000001e+00 2.6260334713262132e+00 -1.3528066427735730e+01 6.4359950042409935e+00 0 1 0 -993 1 2 2.1000000000000001e+00 2.5463640194202295e+00 -1.6483046383772894e+01 6.4280943022387618e+00 0 1 0 -994 1 3 -1.0500000000000000e+00 2.7670577989698710e+00 -1.3599245226532281e+01 8.0541149615482723e+00 0 1 0 -995 1 3 -1.0500000000000000e+00 2.4115228556732085e+00 -1.6390014089725227e+01 8.0528322862442749e+00 0 1 0 -996 1 4 -9.4999999999999996e-01 -1.0785964885834609e-01 -1.5193820735965280e+01 8.1829552962975640e+00 0 1 0 -997 1 3 -1.0500000000000000e+00 1.2415660450237205e+00 -1.7185938541993124e+01 5.9541309734678265e+00 0 1 0 -998 1 3 -1.0500000000000000e+00 2.6586347332325566e+00 -1.5008711746664455e+01 5.9521861384419914e+00 0 1 0 -999 1 3 -1.0500000000000000e+00 3.8118994841845275e+00 -1.7334779054414145e+01 6.1440189839290493e+00 0 1 0 -1000 1 5 4.2499999999999999e-01 3.9906916278648374e-01 -1.4314795620707541e+01 8.0390060720583207e+00 0 1 0 -1001 1 1 1.5750000000000000e+00 5.9506939714474321e+00 -1.6623835068092347e+01 9.1936382786241992e+00 0 1 0 -1002 1 2 2.1000000000000001e+00 -1.0506640576231028e+01 -8.8863436054326126e+00 -6.4424677035855238e+00 1 1 1 -1003 1 2 2.1000000000000001e+00 -1.0483290723862387e+01 -1.4897228405626638e+01 -6.4345414391816869e+00 1 1 1 -1004 1 3 -1.0500000000000000e+00 9.9358456770202679e+00 -1.7781130397438233e+01 -8.0605296334274943e+00 0 1 1 -1005 1 3 -1.0500000000000000e+00 -1.0348413283559834e+01 -1.4990074986278724e+01 -8.0593544612942196e+00 1 1 1 -1006 1 4 -9.4999999999999996e-01 7.6508143783590370e+00 -1.6186548850617925e+01 -8.1894070119890792e+00 0 1 1 -1007 1 3 -1.0500000000000000e+00 6.3014804178836137e+00 -1.4194288585916839e+01 -5.9607271925590553e+00 0 1 1 -1008 1 3 -1.0500000000000000e+00 -1.0595750133023291e+01 -1.6371487270369901e+01 -5.9585283232845940e+00 1 1 1 -1009 1 3 -1.0500000000000000e+00 8.8912083897961480e+00 -1.4045366136980967e+01 -6.1505083848828619e+00 0 1 1 -1010 1 5 4.2499999999999999e-01 7.1439903531083466e+00 -1.7065357851002698e+01 -8.0456195530088959e+00 0 1 1 -1011 1 1 1.5750000000000000e+00 -1.2081144536247820e+01 -1.2140946835520673e+01 9.1936383416856771e+00 1 1 0 -1012 1 2 2.1000000000000001e+00 7.5252171859214521e+00 -1.3369255913399117e+01 -6.4424677800993333e+00 0 1 1 -1013 1 2 2.1000000000000001e+00 7.6048683547046103e+00 -1.0414291306267540e+01 -6.4345364533740872e+00 0 1 1 -1014 1 3 -1.0500000000000000e+00 7.3840365325120381e+00 -1.3298199004567635e+01 -8.0605549168965798e+00 0 1 1 -1015 1 3 -1.0500000000000000e+00 7.7397261633642032e+00 -1.0507136732815026e+01 -8.0593364812444950e+00 0 1 1 -1016 1 4 -9.4999999999999996e-01 -1.0381029451852308e+01 -1.1703616243617095e+01 -8.1894163013224492e+00 1 1 1 -1017 1 3 -1.0500000000000000e+00 8.9096198229319121e+00 -9.7113673904035398e+00 -5.9607474700833842e+00 0 1 1 -1018 1 3 -1.0500000000000000e+00 7.4924216695912946e+00 -1.1888601631193019e+01 -5.9585276380465579e+00 0 1 1 -1019 1 3 -1.0500000000000000e+00 6.3393539149144438e+00 -9.5624805654773333e+00 -6.1504908583355382e+00 0 1 1 -1020 1 5 4.2499999999999999e-01 9.7521586614679343e+00 -1.2582497870895942e+01 -8.0456498211340310e+00 0 1 1 -1021 1 1 1.5750000000000000e+00 5.9666528312158817e+00 -1.0637161674038950e+01 9.1931468103644001e+00 0 1 0 -1022 1 2 2.1000000000000001e+00 5.1778753662721133e+00 -1.8010963984407184e+01 6.4359814805636866e+00 0 1 0 -1023 1 2 2.1000000000000001e+00 5.1545028049949408e+00 -1.2000109022957169e+01 6.4281030161309598e+00 0 1 0 -1024 1 3 -1.0500000000000000e+00 5.3752264146476882e+00 -9.1163121691276299e+00 8.0541203432628947e+00 0 1 0 -1025 1 3 -1.0500000000000000e+00 5.0196713017854648e+00 -1.1907081324390029e+01 8.0528370092718831e+00 0 1 0 -1026 1 4 -9.4999999999999996e-01 -1.2979697389103453e+01 -1.0710875922684368e+01 8.1829544428334522e+00 1 1 0 -1027 1 3 -1.0500000000000000e+00 -1.1630296209217201e+01 -1.2703018689954808e+01 5.9541099221205478e+00 1 1 0 -1028 1 3 -1.0500000000000000e+00 5.2668033030766850e+00 -1.0525836800562153e+01 5.9521941159301512e+00 0 1 0 -1029 1 3 -1.0500000000000000e+00 6.4200409003896226e+00 -1.2851888326745122e+01 6.1440331416663128e+00 0 1 0 -1030 1 5 4.2499999999999999e-01 -1.2472757916081662e+01 -9.8319176933494745e+00 8.0390434094765979e+00 1 1 0 -1031 1 1 1.5750000000000000e+00 3.3584804357961584e+00 -1.5120044269224334e+01 9.1931416749572179e+00 0 1 0 -1032 1 2 2.1000000000000001e+00 -1.2853958426036806e+01 -1.3528056112503791e+01 6.4359801741581606e+00 1 1 0 -1033 1 2 2.1000000000000001e+00 -1.2933643653390329e+01 -1.6483056912757920e+01 6.4281022529867560e+00 1 1 0 -1034 1 3 -1.0500000000000000e+00 -1.2712957273538862e+01 -1.3599246756786883e+01 8.0541258708508607e+00 1 1 0 -1035 1 3 -1.0500000000000000e+00 -1.3068472802163864e+01 -1.6390010426726480e+01 8.0528262007323370e+00 1 1 0 -1036 1 4 -9.4999999999999996e-01 5.0521662927602833e+00 -1.5193788642207085e+01 8.1829741201987432e+00 0 1 0 -1037 1 3 -1.0500000000000000e+00 6.4015896715046452e+00 -1.7185923930494749e+01 5.9541244493280558e+00 0 1 0 -1038 1 3 -1.0500000000000000e+00 -1.2821368685290258e+01 -1.5008710676546100e+01 5.9522034488344904e+00 1 1 0 -1039 1 3 -1.0500000000000000e+00 -1.1668117524798545e+01 -1.7334767401037251e+01 6.1440167764848646e+00 1 1 0 -1040 1 5 4.2499999999999999e-01 5.5590905525768228e+00 -1.4314774286778661e+01 8.0391562840719075e+00 0 1 0 -1041 1 1 1.5750000000000000e+00 -9.5293188214710725e+00 -1.6623826684123888e+01 9.1936328126190716e+00 1 1 0 -1042 1 2 2.1000000000000001e+00 -5.3466469950554503e+00 -8.8863547888654359e+00 -6.4424529044326908e+00 1 1 1 -1043 1 2 2.1000000000000001e+00 -5.3232821656758063e+00 -1.4897218967980935e+01 -6.4345484121686685e+00 1 1 1 -1044 1 3 -1.0500000000000000e+00 -5.5441389512094403e+00 -1.7781128157849743e+01 -8.0605420702790873e+00 1 1 1 -1045 1 3 -1.0500000000000000e+00 -5.1884183273644116e+00 -1.4990078057532681e+01 -8.0593478647888492e+00 1 1 1 -1046 1 4 -9.4999999999999996e-01 -7.8291602923358292e+00 -1.6186518435161432e+01 -8.1893893870051198e+00 1 1 1 -1047 1 3 -1.0500000000000000e+00 -9.1784940192732005e+00 -1.4194272544916783e+01 -5.9607325187992837e+00 1 1 1 -1048 1 3 -1.0500000000000000e+00 -5.4357467498152605e+00 -1.6371486872883263e+01 -5.9585457960351720e+00 1 1 1 -1049 1 3 -1.0500000000000000e+00 -6.5887751078378400e+00 -1.4045377768145462e+01 -6.1505061183693321e+00 1 1 1 -1050 1 5 4.2499999999999999e-01 -8.3359901827017833e+00 -1.7065338169428625e+01 -8.0454801354362822e+00 1 1 1 -1051 1 1 1.5750000000000000e+00 -6.9211531218136324e+00 -1.2140946769776193e+01 9.1936369407535850e+00 1 1 0 -1052 1 2 2.1000000000000001e+00 -7.9548051874856558e+00 -1.3369247354913592e+01 -6.4424672184378995e+00 1 1 1 -1053 1 2 2.1000000000000001e+00 -7.8751437504775899e+00 -1.0414281504434964e+01 -6.4345410387202531e+00 1 1 1 -1054 1 3 -1.0500000000000000e+00 -8.0959680927033695e+00 -1.3298196803434536e+01 -8.0605381269198251e+00 1 1 1 -1055 1 3 -1.0500000000000000e+00 -7.7402694009917266e+00 -1.0507146672218198e+01 -8.0593436744880336e+00 1 1 1 -1056 1 4 -9.4999999999999996e-01 -5.2210352700741893e+00 -1.1703630202846330e+01 -8.1894311727977716e+00 1 1 1 -1057 1 3 -1.0500000000000000e+00 -6.5703560819489564e+00 -9.7113479362165016e+00 -5.9607410747186238e+00 1 1 1 -1058 1 3 -1.0500000000000000e+00 -7.9875793383190201e+00 -1.1888617545808799e+01 -5.9585334894052000e+00 1 1 1 -1059 1 3 -1.0500000000000000e+00 -9.1406320967977006e+00 -9.5624860050644021e+00 -6.1504937073942587e+00 1 1 1 -1060 1 5 4.2499999999999999e-01 -5.7278624840467609e+00 -1.2582509740661457e+01 -8.0457554497395662e+00 1 1 1 -1061 1 1 1.5750000000000000e+00 -9.5133561984343267e+00 -1.0637161443925187e+01 9.1931449257068110e+00 1 1 0 -1062 1 2 2.1000000000000001e+00 -1.0302103162981487e+01 -1.8010973546246127e+01 6.4359819942339911e+00 1 1 0 -1063 1 2 2.1000000000000001e+00 -1.0325485236251158e+01 -1.2000119046399291e+01 6.4281074584691407e+00 1 1 0 -1064 1 3 -1.0500000000000000e+00 -1.0104767986348390e+01 -9.1163139247879545e+00 8.0541026857520492e+00 1 1 0 -1065 1 3 -1.0500000000000000e+00 -1.0460333843012682e+01 -1.1907072686620445e+01 8.0528443316439606e+00 1 1 0 -1066 1 4 -9.4999999999999996e-01 -7.8197018893376633e+00 -1.0710888909838374e+01 8.1829395286487667e+00 1 1 0 -1067 1 3 -1.0500000000000000e+00 -6.4702710783294801e+00 -1.2702999088730675e+01 5.9541157172112893e+00 1 1 0 -1068 1 3 -1.0500000000000000e+00 -1.0213195440240053e+01 -1.0525820371453730e+01 5.9521985271822651e+00 1 1 0 -1069 1 3 -1.0500000000000000e+00 -9.0599710368792579e+00 -1.2851884271772070e+01 6.1440355001063480e+00 1 1 0 -1070 1 5 4.2499999999999999e-01 -7.3127792650248713e+00 -9.8319304014698883e+00 8.0389391760501852e+00 1 1 0 -1071 1 1 1.5750000000000000e+00 -1.2121507533140084e+01 -1.5120052664422875e+01 9.1931470304034590e+00 1 1 0 -1072 1 2 2.1000000000000001e+00 -7.6939667419950801e+00 -1.3528066144827598e+01 6.4359949270123238e+00 1 1 0 -1073 1 2 2.1000000000000001e+00 -7.7736363035098925e+00 -1.6483046674091760e+01 6.4280942646622137e+00 1 1 0 -1074 1 3 -1.0500000000000000e+00 -7.5529421955569074e+00 -1.3599245468551363e+01 8.0541142514246715e+00 1 1 0 -1075 1 3 -1.0500000000000000e+00 -7.9084771877680691e+00 -1.6390013510557839e+01 8.0528318983059464e+00 1 1 0 -1076 1 4 -9.4999999999999996e-01 -1.0427859357572599e+01 -1.5193820182455829e+01 8.1829554940568769e+00 1 1 0 -1077 1 3 -1.0500000000000000e+00 -9.0784339241929697e+00 -1.7185938110398013e+01 5.9541306687748232e+00 1 1 0 -1078 1 3 -1.0500000000000000e+00 -7.6613653461353088e+00 -1.5008711767910862e+01 5.9521866874116398e+00 1 1 0 -1079 1 3 -1.0500000000000000e+00 -6.5081001233818814e+00 -1.7334779316006536e+01 6.1440190441222455e+00 1 1 0 -1080 1 5 4.2499999999999999e-01 -9.9209308239268683e+00 -1.4314795312124453e+01 8.0390077192173415e+00 1 1 0 -1081 1 1 1.5750000000000000e+00 -4.3693061009659697e+00 -1.6623834999276671e+01 9.1936379769479437e+00 1 1 0 -1082 1 2 2.1000000000000001e+00 -1.8664063570919787e-01 -8.8863432803405811e+00 -6.4424677469551810e+00 1 1 1 -1083 1 2 2.1000000000000001e+00 -1.6329097810402793e-01 -1.4897228323503647e+01 -6.4345412625064382e+00 1 1 1 -1084 1 3 -1.0500000000000000e+00 -3.8415424661157438e-01 -1.7781129628630708e+01 -8.0605294520712274e+00 1 1 1 -1085 1 3 -1.0500000000000000e+00 -2.8413217122468026e-02 -1.4990075729797402e+01 -8.0593541281939132e+00 1 1 1 -1086 1 4 -9.4999999999999996e-01 -2.6691856611378615e+00 -1.6186549289357281e+01 -8.1894073233154465e+00 1 1 1 -1087 1 3 -1.0500000000000000e+00 -4.0185192058825869e+00 -1.4194288256372477e+01 -5.9607267686664311e+00 1 1 1 -1088 1 3 -1.0500000000000000e+00 -2.7575005025033228e-01 -1.6371487406479059e+01 -5.9585294057433886e+00 1 1 1 -1089 1 3 -1.0500000000000000e+00 -1.4287919277961123e+00 -1.4045366019988233e+01 -6.1505084048473080e+00 1 1 1 -1090 1 5 4.2499999999999999e-01 -3.1760098512671009e+00 -1.7065358014346177e+01 -8.0456213091621525e+00 1 1 1 -1091 1 1 1.5750000000000000e+00 -1.7611447082543581e+00 -1.2140947006232711e+01 9.1936384925219343e+00 1 1 0 -1092 1 2 2.1000000000000001e+00 -2.7947833334742578e+00 -1.3369255833313584e+01 -6.4424679239504536e+00 1 1 1 -1093 1 2 2.1000000000000001e+00 -2.7151320890150723e+00 -1.0414292035495656e+01 -6.4345365349275232e+00 1 1 1 -1094 1 3 -1.0500000000000000e+00 -2.9359633864487167e+00 -1.3298199302942400e+01 -8.0605558474868584e+00 1 1 1 -1095 1 3 -1.0500000000000000e+00 -2.5802737289353015e+00 -1.0507135999068634e+01 -8.0593367229262789e+00 1 1 1 -1096 1 4 -9.4999999999999996e-01 -6.1029269090347782e-02 -1.1703615903830615e+01 -8.1894161277141180e+00 1 1 1 -1097 1 3 -1.0500000000000000e+00 -1.4103806657889049e+00 -9.7113672812162282e+00 -5.9607478027659599e+00 1 1 1 -1098 1 3 -1.0500000000000000e+00 -2.8275782608809799e+00 -1.1888601242038703e+01 -5.9585270905330248e+00 1 1 1 -1099 1 3 -1.0500000000000000e+00 -3.9806455024529077e+00 -9.5624806910509168e+00 -6.1504908768056445e+00 1 1 1 -1100 1 5 4.2499999999999999e-01 -5.6784118232465808e-01 -1.2582497522733426e+01 -8.0456483776788108e+00 1 1 1 -1101 1 1 1.5750000000000000e+00 -4.3533469166295102e+00 -1.0637161941409968e+01 9.1931466279762688e+00 1 1 0 -1102 1 2 2.1000000000000001e+00 -5.1421242323834440e+00 -1.8010964249264401e+01 6.4359814700617477e+00 1 1 0 -1103 1 2 2.1000000000000001e+00 -5.1654968648540116e+00 -1.2000108869836776e+01 6.4281033826662970e+00 1 1 0 -1104 1 3 -1.0500000000000000e+00 -4.9447740518312981e+00 -9.1163119838152724e+00 8.0541208305003771e+00 1 1 0 -1105 1 3 -1.0500000000000000e+00 -5.3003292400556994e+00 -1.1907081523711627e+01 8.0528368570269038e+00 1 1 0 -1106 1 4 -9.4999999999999996e-01 -2.6596975609644353e+00 -1.0710876671328320e+01 8.1829540418686726e+00 1 1 0 -1107 1 3 -1.0500000000000000e+00 -1.3102967405498305e+00 -1.2703018844561765e+01 5.9541098017479914e+00 1 1 0 -1108 1 3 -1.0500000000000000e+00 -5.0531971125971715e+00 -1.0525837012779654e+01 5.9521936676734288e+00 1 1 0 -1109 1 3 -1.0500000000000000e+00 -3.8999587373145639e+00 -1.2851888639718560e+01 6.1440326350946801e+00 1 1 0 -1110 1 5 4.2499999999999999e-01 -2.1527582625456603e+00 -9.8319182168488304e+00 8.0390404001017757e+00 1 1 0 -1111 1 1 1.5750000000000000e+00 -6.9615195399090135e+00 -1.5120044188301915e+01 9.1931419288498510e+00 1 1 0 -1112 1 2 2.1000000000000001e+00 -2.5339585653648697e+00 -1.3528056455243178e+01 6.4359804193401242e+00 1 1 0 -1113 1 2 2.1000000000000001e+00 -2.6136441830708090e+00 -1.6483056479457897e+01 6.4281018808823198e+00 1 1 0 -1114 1 3 -1.0500000000000000e+00 -2.3929570991997231e+00 -1.3599246776377498e+01 8.0541258935608298e+00 1 1 0 -1115 1 3 -1.0500000000000000e+00 -2.7484725571750399e+00 -1.6390010736806076e+01 8.0528264711468935e+00 1 1 0 -1116 1 4 -9.4999999999999996e-01 -5.2678337090553065e+00 -1.5193788165127659e+01 8.1829742284955529e+00 1 1 0 -1117 1 3 -1.0500000000000000e+00 -3.9184101788552468e+00 -1.7185923765773964e+01 5.9541244091178598e+00 1 1 0 -1118 1 3 -1.0500000000000000e+00 -2.5013685629992448e+00 -1.5008710686713700e+01 5.9522033519993389e+00 1 1 0 -1119 1 3 -1.0500000000000000e+00 -1.3481177660942105e+00 -1.7334767344129535e+01 6.1440168516164491e+00 1 1 0 -1120 1 5 4.2499999999999999e-01 -4.7609092110786975e+00 -1.4314774014546140e+01 8.0391576594168868e+00 1 1 0 -1121 1 1 1.5750000000000000e+00 8.4702278437567813e-01 -7.6580232655670812e+00 9.1936367166763624e+00 0 1 0 -1122 1 2 2.1000000000000001e+00 5.0297006416917132e+00 7.9484059064306223e-02 -6.4424616072269298e+00 0 1 1 -1123 1 2 2.1000000000000001e+00 5.0530476677862790e+00 -5.9313937646500747e+00 -6.4345523942143377e+00 0 1 1 -1124 1 3 -1.0500000000000000e+00 4.8322083965292535e+00 -8.8153100460475606e+00 -8.0605579352060097e+00 0 1 1 -1125 1 3 -1.0500000000000000e+00 5.1879128429810493e+00 -6.0242487098424640e+00 -8.0593461534535624e+00 0 1 1 -1126 1 4 -9.4999999999999996e-01 2.5471361408688615e+00 -7.2207528703077557e+00 -8.1894351371722358e+00 0 1 1 -1127 1 3 -1.0500000000000000e+00 1.1978328571825969e+00 -5.2284444301903292e+00 -5.9607333513353664e+00 0 1 1 -1128 1 3 -1.0500000000000000e+00 4.9405815890627913e+00 -7.4056921688323918e+00 -5.9585160703411431e+00 0 1 1 -1129 1 3 -1.0500000000000000e+00 3.7875589443517192e+00 -5.0795530548692049e+00 -6.1505080854452663e+00 0 1 1 -1130 1 5 4.2499999999999999e-01 2.0403189217065272e+00 -8.0996159618770101e+00 -8.0458306129470607e+00 0 1 1 -1131 1 1 1.5750000000000000e+00 3.4551805309799555e+00 -3.1750994810300153e+00 9.1936339027276048e+00 0 1 0 -1132 1 2 2.1000000000000001e+00 2.4215212035344518e+00 -4.4034491530480739e+00 -6.4424571217207802e+00 0 1 1 -1133 1 2 2.1000000000000001e+00 2.5012043331728666e+00 -1.4484744055647418e+00 -6.4345430279127775e+00 0 1 1 -1134 1 3 -1.0500000000000000e+00 2.2803539505610697e+00 -4.3323833660358364e+00 -8.0605258108252205e+00 0 1 1 -1135 1 3 -1.0500000000000000e+00 2.6360802955348941e+00 -1.5413397332259180e+00 -8.0593504769284650e+00 0 1 1 -1136 1 4 -9.4999999999999996e-01 5.1553306473428808e+00 -2.7377831359752083e+00 -8.1893975367123950e+00 0 1 1 -1137 1 3 -1.0500000000000000e+00 3.8059983762442684e+00 -7.4553448804683953e-01 -5.9607324711289582e+00 0 1 1 -1138 1 3 -1.0500000000000000e+00 2.3887570726922274e+00 -2.9227626518386991e+00 -5.9585500629556050e+00 0 1 1 -1139 1 3 -1.0500000000000000e+00 1.2357160071709661e+00 -5.9665037297639500e-01 -6.1505012036351134e+00 0 1 1 -1140 1 5 4.2499999999999999e-01 4.6484937716044001e+00 -3.6166060056537965e+00 -8.0455230131872870e+00 0 1 1 -1141 1 1 1.5750000000000000e+00 8.6298531122536914e-01 -1.6713268084760990e+00 9.1931454150014353e+00 0 1 0 -1142 1 2 2.1000000000000001e+00 7.4231487268695773e-02 -9.0451288937312082e+00 6.4359748300959829e+00 0 1 0 -1143 1 2 2.1000000000000001e+00 5.0862435699427166e-02 -3.0343150555734812e+00 6.4281002242315228e+00 0 1 0 -1144 1 3 -1.0500000000000000e+00 2.7156279772418301e-01 -1.5050995827601810e-01 8.0541033055399680e+00 0 1 0 -1145 1 3 -1.0500000000000000e+00 -8.3982031259724366e-02 -2.9412651342227321e+00 8.0528361691957926e+00 0 1 0 -1146 1 4 -9.4999999999999996e-01 2.5566338054460775e+00 -1.7450963130005661e+00 8.1829354408637407e+00 0 1 0 -1147 1 3 -1.0500000000000000e+00 3.9060828322134107e+00 -3.7371824538973115e+00 5.9541269408037341e+00 0 1 0 -1148 1 3 -1.0500000000000000e+00 1.6313395171608747e-01 -1.5599865149333638e+00 5.9522097757624319e+00 0 1 0 -1149 1 3 -1.0500000000000000e+00 1.3163820483106132e+00 -3.8860413266369562e+00 6.1440220138279358e+00 0 1 0 -1150 1 5 4.2499999999999999e-01 3.0635572828589979e+00 -8.6610823719537322e-01 8.0388716107541818e+00 0 1 0 -1151 1 1 1.5750000000000000e+00 -1.7451821647999690e+00 -6.1542224885308414e+00 9.1931438632881530e+00 0 1 0 -1152 1 2 2.1000000000000001e+00 2.6823773363600836e+00 -4.5622501456258107e+00 6.4359944262164994e+00 0 1 0 -1153 1 2 2.1000000000000001e+00 2.6026938898999319e+00 -7.5172128468589250e+00 6.4281009928530715e+00 0 1 0 -1154 1 3 -1.0500000000000000e+00 2.8233864525624490e+00 -4.6334075597788917e+00 8.0541258951475108e+00 0 1 0 -1155 1 3 -1.0500000000000000e+00 2.4678495683205419e+00 -7.4241857794933104e+00 8.0528359019154507e+00 0 1 0 -1156 1 4 -9.4999999999999996e-01 -5.1498278778744577e-02 -6.2279375048231778e+00 8.1829905871126414e+00 0 1 0 -1157 1 3 -1.0500000000000000e+00 1.2978954189885741e+00 -8.2201150373346188e+00 5.9541246386945623e+00 0 1 0 -1158 1 3 -1.0500000000000000e+00 2.7149775870672244e+00 -6.0428750652710281e+00 5.9521581130832271e+00 0 1 0 -1159 1 3 -1.0500000000000000e+00 3.8682230635120050e+00 -8.3689695485227933e+00 6.1440290574073693e+00 0 1 0 -1160 1 5 4.2499999999999999e-01 4.5542119168019468e-01 -5.3488994735314019e+00 8.0392998211117188e+00 0 1 0 -1161 1 1 1.5750000000000000e+00 6.0070359199026413e+00 -7.6580317990401383e+00 9.1936420334956352e+00 0 1 0 -1162 1 2 2.1000000000000001e+00 -1.0450293015577390e+01 7.9495280223444098e-02 -6.4424763918604233e+00 1 1 1 -1163 1 2 2.1000000000000001e+00 -1.0426960773896065e+01 -5.9314037196641181e+00 -6.4345450407107982e+00 1 1 1 -1164 1 3 -1.0500000000000000e+00 9.9921921571101286e+00 -8.8153118818805645e+00 -8.0605456616730571e+00 0 1 1 -1165 1 3 -1.0500000000000000e+00 -1.0292082062970158e+01 -6.0242459328472098e+00 -8.0593528751957386e+00 1 1 1 -1166 1 4 -9.4999999999999996e-01 7.7071097346887818e+00 -7.2207851871691879e+00 -8.1894536617151434e+00 0 1 1 -1167 1 3 -1.0500000000000000e+00 6.3578053299953972e+00 -5.2284613945548042e+00 -5.9607278952264320e+00 0 1 1 -1168 1 3 -1.0500000000000000e+00 -1.0539422044436927e+01 -7.4056920979980116e+00 -5.9584989814049418e+00 1 1 1 -1169 1 3 -1.0500000000000000e+00 8.9475427729909818e+00 -5.0795413119982644e+00 -6.1505108444496814e+00 0 1 1 -1170 1 5 4.2499999999999999e-01 7.2002983553707018e+00 -8.0996371163886227e+00 -8.0459783924122128e+00 0 1 1 -1171 1 1 1.5750000000000000e+00 -1.2024810924064735e+01 -3.1750992500711241e+00 9.1936353810280806e+00 1 1 0 -1172 1 2 2.1000000000000001e+00 7.5815439799702844e+00 -4.4034577477820722e+00 -6.4424579544837721e+00 0 1 1 -1173 1 2 2.1000000000000001e+00 7.6612148088231109e+00 -1.4484842350497935e+00 -6.4345384862173862e+00 0 1 1 -1174 1 3 -1.0500000000000000e+00 7.4403582637752663e+00 -4.3323852024538532e+00 -8.0605421667547734e+00 0 1 1 -1175 1 3 -1.0500000000000000e+00 7.7960760201848451e+00 -1.5413304457284198e+00 -8.0593433188062864e+00 0 1 1 -1176 1 4 -9.4999999999999996e-01 -1.0324662920126057e+01 -2.7377676996020437e+00 -8.1893817201369004e+00 1 1 1 -1177 1 3 -1.0500000000000000e+00 8.9659761219978016e+00 -7.4555247647951717e-01 -5.9607387977563846e+00 0 1 1 -1178 1 3 -1.0500000000000000e+00 7.5487582612097164e+00 -2.9227465837537405e+00 -5.9585440533042542e+00 0 1 1 -1179 1 3 -1.0500000000000000e+00 6.3957019831255764e+00 -5.9664489491982309e-01 -6.1504987250233718e+00 0 1 1 -1180 1 5 4.2499999999999999e-01 9.8085161191182273e+00 -3.6165924184139993e+00 -8.0454097308368144e+00 0 1 1 -1181 1 1 1.5750000000000000e+00 6.0229947156425219e+00 -1.6713272376378114e+00 9.1931471332917951e+00 0 1 0 -1182 1 2 2.1000000000000001e+00 5.2342090625861122e+00 -9.0451198953531229e+00 6.4359743484420608e+00 0 1 0 -1183 1 2 2.1000000000000001e+00 5.2108500666849515e+00 -3.0343058583757365e+00 6.4280961143861379e+00 0 1 0 -1184 1 3 -1.0500000000000000e+00 5.4315568698103682e+00 -1.5050754889598394e-01 8.0541211115717530e+00 0 1 0 -1185 1 3 -1.0500000000000000e+00 5.0760229842966851e+00 -2.9412748570574045e+00 8.0528289018931147e+00 0 1 0 -1186 1 4 -9.4999999999999996e-01 -1.2923362686474924e+01 -1.7450848151666776e+00 8.1829494061006542e+00 1 1 0 -1187 1 3 -1.0500000000000000e+00 -1.1573943220704928e+01 -3.7372026818802766e+00 5.9541212903106597e+00 1 1 0 -1188 1 3 -1.0500000000000000e+00 5.3231325027349374e+00 -1.5600025867974843e+00 5.9522047165104084e+00 0 1 0 -1189 1 3 -1.0500000000000000e+00 6.4763937387235302e+00 -3.8860452169511657e+00 6.1440192700819232e+00 0 1 0 -1190 1 5 4.2499999999999999e-01 -1.2416422447133380e+01 -8.6609651618983463e-01 8.0389687852832665e+00 1 1 0 -1191 1 1 1.5750000000000000e+00 3.4148053181702878e+00 -6.1542140440503630e+00 9.1931386649716700e+00 0 1 0 -1192 1 2 2.1000000000000001e+00 -1.2797614044359129e+01 -4.5622391586108471e+00 6.4359796755651928e+00 1 1 0 -1193 1 2 2.1000000000000001e+00 -1.2877314202121172e+01 -7.5172235788753987e+00 6.4281086874059419e+00 1 1 0 -1194 1 3 -1.0500000000000000e+00 -1.2656628923487901e+01 -4.6334094538476478e+00 8.0541365991700147e+00 1 1 0 -1195 1 3 -1.0500000000000000e+00 -1.3012145728905931e+01 -7.4241822509387418e+00 8.0528298995085592e+00 1 1 0 -1196 1 4 -9.4999999999999996e-01 5.1085285285654010e+00 -6.2279042258343331e+00 8.1830105238613839e+00 0 1 0 -1197 1 3 -1.0500000000000000e+00 6.4579201987175878e+00 -8.2200996294511413e+00 5.9541184262943627e+00 0 1 0 -1198 1 3 -1.0500000000000000e+00 -1.2765025619162541e+01 -6.0428744287741054e+00 5.9521756927266267e+00 1 1 0 -1199 1 3 -1.0500000000000000e+00 -1.1611794182671192e+01 -8.3689574783603700e+00 6.1440264520959502e+00 1 1 0 -1200 1 5 4.2499999999999999e-01 5.6154437598182660e+00 -5.3488757784566658e+00 8.0394584888938070e+00 0 1 0 -1201 1 1 1.5750000000000000e+00 -9.4729773030317794e+00 -7.6580233252183270e+00 9.1936366694221832e+00 1 1 0 -1202 1 2 2.1000000000000001e+00 -5.2902987446636125e+00 7.9484321877622222e-02 -6.4424614835376728e+00 1 1 1 -1203 1 2 2.1000000000000001e+00 -5.2669512894979746e+00 -5.9313935295981075e+00 -6.4345521375661248e+00 1 1 1 -1204 1 3 -1.0500000000000000e+00 -5.4877916891509262e+00 -8.8153094923822373e+00 -8.0605578311834094e+00 1 1 1 -1205 1 3 -1.0500000000000000e+00 -5.1320874487160113e+00 -6.0242489357945139e+00 -8.0593461503730968e+00 1 1 1 -1206 1 4 -9.4999999999999996e-01 -7.7728631827928893e+00 -7.2207518961129562e+00 -8.1894347344941494e+00 1 1 1 -1207 1 3 -1.0500000000000000e+00 -9.1221676357991832e+00 -5.2284443001575482e+00 -5.9607337021365758e+00 1 1 1 -1208 1 3 -1.0500000000000000e+00 -5.3794188054280401e+00 -7.4056919133372130e+00 -5.9585167260978453e+00 1 1 1 -1209 1 3 -1.0500000000000000e+00 -6.5324410007864140e+00 -5.0795531783307730e+00 -6.1505082082244877e+00 1 1 1 -1210 1 5 4.2499999999999999e-01 -8.2796807529920091e+00 -8.0996152957469771e+00 -8.0458269851436377e+00 1 1 1 -1211 1 1 1.5750000000000000e+00 -6.8648193207727157e+00 -3.1750993988657363e+00 9.1936340184547376e+00 1 1 0 -1212 1 2 2.1000000000000001e+00 -7.8984787774037670e+00 -4.4034493335665754e+00 -6.4424573711715984e+00 1 1 1 -1213 1 2 2.1000000000000001e+00 -7.8187962865526366e+00 -1.4484736242006377e+00 -6.4345431293552142e+00 1 1 1 -1214 1 3 -1.0500000000000000e+00 -8.0396461317643055e+00 -4.3323833036530388e+00 -8.0605255549319743e+00 1 1 1 -1215 1 3 -1.0500000000000000e+00 -7.6839196020704632e+00 -1.5413397193538962e+00 -8.0593506126489753e+00 1 1 1 -1216 1 4 -9.4999999999999996e-01 -5.1646694323993323e+00 -2.7377828746714190e+00 -8.1893976905136832e+00 1 1 1 -1217 1 3 -1.0500000000000000e+00 -6.5140013675298203e+00 -7.4553408621003214e-01 -5.9607326599656574e+00 1 1 1 -1218 1 3 -1.0500000000000000e+00 -7.9312429921320682e+00 -2.9227627440075619e+00 -5.9585499900858849e+00 1 1 1 -1219 1 3 -1.0500000000000000e+00 -9.0842839835338065e+00 -5.9665059109964957e-01 -6.1505013365473369e+00 1 1 1 -1220 1 5 4.2499999999999999e-01 -5.6715064002788909e+00 -3.6166062753369719e+00 -8.0455239544889672e+00 1 1 1 -1221 1 1 1.5750000000000000e+00 -9.4570145004728179e+00 -1.6713268887520627e+00 9.1931451047570434e+00 1 1 0 -1222 1 2 2.1000000000000001e+00 -1.0245768554696422e+01 -9.0451291887334850e+00 6.4359751513977947e+00 1 1 0 -1223 1 2 2.1000000000000001e+00 -1.0269137954528176e+01 -3.0343150798318153e+00 6.4281005246690643e+00 1 1 0 -1224 1 3 -1.0500000000000000e+00 -1.0048437280241860e+01 -1.5050931757356167e-01 8.0541034233813562e+00 1 1 0 -1225 1 3 -1.0500000000000000e+00 -1.0403982381201681e+01 -2.9412653897784651e+00 8.0528362691868480e+00 1 1 0 -1226 1 4 -9.4999999999999996e-01 -7.7633664256876340e+00 -1.7450970824089147e+00 8.1829349554696620e+00 1 1 0 -1227 1 3 -1.0500000000000000e+00 -6.4139168589828959e+00 -3.7371822759663971e+00 5.9541271825894846e+00 1 1 0 -1228 1 3 -1.0500000000000000e+00 -1.0156866061605893e+01 -1.5599862614345987e+00 5.9522089326467871e+00 1 1 0 -1229 1 3 -1.0500000000000000e+00 -9.0036179148864903e+00 -3.8860418027826178e+00 6.1440219303818058e+00 1 1 0 -1230 1 5 4.2499999999999999e-01 -7.2564430166352647e+00 -8.6610861181779697e-01 8.0388684521422960e+00 1 1 0 -1231 1 1 1.5750000000000000e+00 -1.2065182081870857e+01 -6.1542225350720248e+00 9.1931439110124948e+00 1 1 0 -1232 1 2 2.1000000000000001e+00 -7.6376228395315966e+00 -4.5622496727582575e+00 6.4359946705514783e+00 1 1 0 -1233 1 2 2.1000000000000001e+00 -7.7173060016143831e+00 -7.5172132790716208e+00 6.4281005852309825e+00 1 1 0 -1234 1 3 -1.0500000000000000e+00 -7.4966133366732546e+00 -4.6334080305519123e+00 8.0541249886634674e+00 1 1 0 -1235 1 3 -1.0500000000000000e+00 -7.8521505280754020e+00 -7.4241854610629545e+00 8.0528357473265331e+00 1 1 0 -1236 1 4 -9.4999999999999996e-01 -1.0371498687204594e+01 -6.2279384070688195e+00 8.1829903050401605e+00 1 1 0 -1237 1 3 -1.0500000000000000e+00 -9.0221051208568284e+00 -8.2201150031478480e+00 5.9541248287337076e+00 1 1 0 -1238 1 3 -1.0500000000000000e+00 -7.6050225829956677e+00 -6.0428751844446591e+00 5.9521586085867639e+00 1 1 0 -1239 1 3 -1.0500000000000000e+00 -6.4517770392012332e+00 -8.3689695952358161e+00 6.1440292062209494e+00 1 1 0 -1240 1 5 4.2499999999999999e-01 -9.8645788768205804e+00 -5.3488995345633406e+00 8.0392975567042662e+00 1 1 0 -1241 1 1 1.5750000000000000e+00 -4.3129638640606647e+00 -7.6580318027278675e+00 9.1936418211766444e+00 1 1 0 -1242 1 2 2.1000000000000001e+00 -1.3029281142709515e-01 7.9495519716360263e-02 -6.4424764398927401e+00 1 1 1 -1243 1 2 2.1000000000000001e+00 -1.0696070772270616e-01 -5.9314030913469704e+00 -6.4345451084165770e+00 1 1 1 -1244 1 3 -1.0500000000000000e+00 -3.2780783550479420e-01 -8.8153116510251959e+00 -8.0605450983335576e+00 1 1 1 -1245 1 3 -1.0500000000000000e+00 2.7917794055881018e-02 -6.0242464388696852e+00 -8.0593530751785352e+00 1 1 1 -1246 1 4 -9.4999999999999996e-01 -2.6128902760772847e+00 -7.2207854612448905e+00 -8.1894539864596751e+00 1 1 1 -1247 1 3 -1.0500000000000000e+00 -3.9621949760983775e+00 -5.2284614730954679e+00 -5.9607279014893146e+00 1 1 1 -1248 1 3 -1.0500000000000000e+00 -2.1942223631894819e-01 -7.4056928858360198e+00 -5.9584995317455478e+00 1 1 1 -1249 1 3 -1.0500000000000000e+00 -1.3724576813688874e+00 -5.0795414924275804e+00 -6.1505107620254549e+00 1 1 1 -1250 1 5 4.2499999999999999e-01 -3.1197019062670854e+00 -8.0996374434774836e+00 -8.0459798390211894e+00 1 1 1 -1251 1 1 1.5750000000000000e+00 -1.7048111758544344e+00 -3.1750992595861227e+00 9.1936354972139753e+00 1 1 0 -1252 1 2 2.1000000000000001e+00 -2.7384556352869289e+00 -4.4034574851471611e+00 -6.4424578813038398e+00 1 1 1 -1253 1 2 2.1000000000000001e+00 -2.6587848481030463e+00 -1.4484848879477177e+00 -6.4345385799020995e+00 1 1 1 -1254 1 3 -1.0500000000000000e+00 -2.8796417968849735e+00 -4.3323855871350911e+00 -8.0605432722549342e+00 1 1 1 -1255 1 3 -1.0500000000000000e+00 -2.5239242999675540e+00 -1.5413297694083674e+00 -8.0593436543609869e+00 1 1 1 -1256 1 4 -9.4999999999999996e-01 -4.6629080053524063e-03 -2.7377676875088639e+00 -8.1893817148421171e+00 1 1 1 -1257 1 3 -1.0500000000000000e+00 -1.3540245806109894e+00 -7.4555242253029164e-01 -5.9607389591077791e+00 1 1 1 -1258 1 3 -1.0500000000000000e+00 -2.7712418210181919e+00 -2.9227458320412136e+00 -5.9585435577682500e+00 1 1 1 -1259 1 3 -1.0500000000000000e+00 -3.9242977076190213e+00 -5.9664519952647410e-01 -6.1504986716818921e+00 1 1 1 -1260 1 5 4.2499999999999999e-01 -5.1148396370540539e-01 -3.6165922980280598e+00 -8.0454092585231791e+00 1 1 1 -1261 1 1 1.5750000000000000e+00 -4.2970049854153896e+00 -1.6713273587868755e+00 9.1931469757790332e+00 1 1 0 -1262 1 2 2.1000000000000001e+00 -5.0857900375752543e+00 -9.0451198373834831e+00 6.4359741821119183e+00 1 1 0 -1263 1 2 2.1000000000000001e+00 -5.1091497653069275e+00 -3.0343053751042728e+00 6.4280964273632488e+00 1 1 0 -1264 1 3 -1.0500000000000000e+00 -4.8884434382084656e+00 -1.5050741393750400e-01 8.0541215270248365e+00 1 1 0 -1265 1 3 -1.0500000000000000e+00 -5.2439776101441780e+00 -2.9412750702577100e+00 8.0528286058062442e+00 1 1 0 -1266 1 4 -9.4999999999999996e-01 -2.6033623405129021e+00 -1.7450848566840129e+00 8.1829492501574848e+00 1 1 0 -1267 1 3 -1.0500000000000000e+00 -1.2539436622602231e+00 -3.7372027388727549e+00 5.9541211418112390e+00 1 1 0 -1268 1 3 -1.0500000000000000e+00 -4.9968680865957600e+00 -1.5600029077844368e+00 5.9522041722462600e+00 1 1 0 -1269 1 3 -1.0500000000000000e+00 -3.8436055814310057e+00 -3.8860458403622662e+00 6.1440188029260252e+00 1 1 0 -1270 1 5 4.2499999999999999e-01 -2.0964225177732381e+00 -8.6609696160275718e-01 8.0389679472175466e+00 1 1 0 -1271 1 1 1.5750000000000000e+00 -6.9051946611557753e+00 -6.1542138113333085e+00 9.1931388891381687e+00 1 1 0 -1272 1 2 2.1000000000000001e+00 -2.4776142909533601e+00 -4.5622398820468000e+00 6.4359798694114190e+00 1 1 0 -1273 1 2 2.1000000000000001e+00 -2.5573143147767201e+00 -7.5172234008194909e+00 6.4281086902173321e+00 1 1 0 -1274 1 3 -1.0500000000000000e+00 -2.3366289199841077e+00 -4.6334093744962033e+00 8.0541367183386292e+00 1 1 0 -1275 1 3 -1.0500000000000000e+00 -2.6921456216065156e+00 -7.4241824167294066e+00 8.0528298697445564e+00 1 1 0 -1276 1 4 -9.4999999999999996e-01 -5.2114715448903457e+00 -6.2279037997317630e+00 8.1830105735514138e+00 1 1 0 -1277 1 3 -1.0500000000000000e+00 -3.8620796140305327e+00 -8.2200995051782648e+00 5.9541181403811656e+00 1 1 0 -1278 1 3 -1.0500000000000000e+00 -2.4450256686773244e+00 -6.0428738521167240e+00 5.9521755762040041e+00 1 1 0 -1279 1 3 -1.0500000000000000e+00 -1.2917948276903886e+00 -8.3689575013840543e+00 6.1440266271082677e+00 1 1 0 -1280 1 5 4.2499999999999999e-01 -4.7045561105828249e+00 -5.3488758174892617e+00 8.0394595369517425e+00 1 1 0 +1 1 1 1.5750000000000000e+00 2.5999859887541152e+00 1.4895295600930361e+00 -3.2684095454396100e-03 0 0 0 +2 1 2 2.1000000000000001e+00 3.3890158510276365e+00 8.8633001207774171e+00 2.7539653683351801e+00 0 0 0 +3 1 2 2.1000000000000001e+00 3.4122910819528869e+00 2.8524994338649421e+00 2.7618119426027334e+00 0 0 0 +4 1 3 -1.0500000000000000e+00 3.1917106615190871e+00 -3.1338269933883112e-02 1.1357135267887219e+00 0 0 0 +5 1 3 -1.0500000000000000e+00 3.5469715140592335e+00 2.7595296221569008e+00 1.1370155152705124e+00 0 0 0 +6 1 4 -9.4999999999999996e-01 9.0629865585113478e-01 1.5632893985929819e+00 1.0069802353213007e+00 0 0 0 +7 1 3 -1.0500000000000000e+00 -4.4288757751145802e-01 3.5553420116799757e+00 3.2357631024135358e+00 0 0 0 +8 1 3 -1.0500000000000000e+00 3.3001891233613350e+00 1.3781620274833877e+00 3.2374587487515178e+00 0 0 0 +9 1 3 -1.0500000000000000e+00 2.1467877066985572e+00 3.7041759320173213e+00 3.0459627186065976e+00 0 0 0 +10 1 5 4.2499999999999999e-01 3.9940955153589464e-01 6.8440286676932871e-01 1.1507107600825695e+00 0 0 0 +11 1 1 1.5750000000000000e+00 5.2081610166521486e+00 5.9724603411204953e+00 -3.2678269427819373e-03 0 0 0 +12 1 2 2.1000000000000001e+00 7.8082390717283801e-01 4.3803873151640857e+00 2.7539573196414509e+00 0 0 0 +13 1 2 2.1000000000000001e+00 8.6049184758384811e-01 7.3353954630155727e+00 2.7618077229661608e+00 0 0 0 +14 1 3 -1.0500000000000000e+00 6.3985291874622341e-01 4.4515561398457919e+00 1.1357491950576897e+00 0 0 0 +15 1 3 -1.0500000000000000e+00 9.9516171983727020e-01 7.2424161873666044e+00 1.1369982112775414e+00 0 0 0 +16 1 4 -9.4999999999999996e-01 3.5145105035101025e+00 6.0462386370433165e+00 1.0069819170376704e+00 0 0 0 +17 1 3 -1.0500000000000000e+00 2.1653116942489294e+00 8.0382453753562579e+00 3.2357864576820852e+00 0 0 0 +18 1 3 -1.0500000000000000e+00 7.4835045014725310e-01 5.8610807683013810e+00 3.2374554227766854e+00 0 0 0 +19 1 3 -1.0500000000000000e+00 -4.0504297107989196e-01 8.1871235044640613e+00 3.0459446104666839e+00 0 0 0 +20 1 5 4.2499999999999999e-01 3.0075427813219715e+00 5.1673094182610200e+00 1.1507483385791737e+00 0 0 0 +21 1 1 1.5750000000000000e+00 2.6161048042733217e+00 7.4761708036165011e+00 -3.7559789002870048e-03 0 0 0 +22 1 2 2.1000000000000001e+00 1.8270583837568388e+00 1.0238224436981014e-01 -2.7609433636234240e+00 0 0 0 +23 1 2 2.1000000000000001e+00 1.8037926928806804e+00 6.1131912799914794e+00 -2.7688607211148550e+00 0 0 0 +24 1 3 -1.0500000000000000e+00 2.0245843840439779e+00 8.9971802013490674e+00 -1.1427990238002010e+00 0 0 0 +25 1 3 -1.0500000000000000e+00 1.6690794936693152e+00 6.2059206004470688e+00 -1.1439630092406396e+00 0 0 0 +26 1 4 -9.4999999999999996e-01 4.3099221099139733e+00 7.4024984100470839e+00 -1.0139954105990832e+00 0 0 0 +27 1 3 -1.0500000000000000e+00 5.6590031416114179e+00 5.4102611437460766e+00 -3.2425548174288927e+00 0 0 0 +28 1 3 -1.0500000000000000e+00 1.9161020068286181e+00 7.5874974627099085e+00 -3.2446533398602568e+00 0 0 0 +29 1 3 -1.0500000000000000e+00 3.0692592992822245e+00 5.2614642342074163e+00 -3.0529614390734992e+00 0 0 0 +30 1 5 4.2499999999999999e-01 4.8166943688168953e+00 8.2812214959912609e+00 -1.1575736167124671e+00 0 0 0 +31 1 1 1.5750000000000000e+00 7.9432589838539513e-03 2.9932322017580155e+00 -3.7548310874804258e-03 0 0 0 +32 1 2 2.1000000000000001e+00 4.4352567674819241e+00 4.5852778048151954e+00 -2.7609429803808379e+00 0 0 0 +33 1 2 2.1000000000000001e+00 4.3556162421312727e+00 1.6303072110574242e+00 -2.7688546110084076e+00 0 0 0 +34 1 3 -1.0500000000000000e+00 4.5764329813965201e+00 4.5142930965604897e+00 -1.1428117296192752e+00 0 0 0 +35 1 3 -1.0500000000000000e+00 4.2208908922051336e+00 1.7230220252737531e+00 -1.1439381753911206e+00 0 0 0 +36 1 4 -9.4999999999999996e-01 1.7016840076240793e+00 2.9195149987798672e+00 -1.0140049080257008e+00 0 0 0 +37 1 3 -1.0500000000000000e+00 3.0508094436907065e+00 9.2735955111261248e-01 -3.2425715481628181e+00 0 0 0 +38 1 3 -1.0500000000000000e+00 4.4679443003019212e+00 3.1046094096202950e+00 -3.2446642002284571e+00 0 0 0 +39 1 3 -1.0500000000000000e+00 5.6210980414275298e+00 7.7850985095940217e-01 -3.0529442198684507e+00 0 0 0 +40 1 5 4.2499999999999999e-01 2.2085508398324158e+00 3.7983231087392824e+00 -1.1577011829365311e+00 0 0 0 +41 1 1 1.5750000000000000e+00 7.7600001218919523e+00 1.4895196291109798e+00 -3.2657864259189040e-03 0 0 0 +42 1 2 2.1000000000000001e+00 -1.2091006019115589e+01 8.8632974450891417e+00 2.7539547041448795e+00 1 0 0 +43 1 2 2.1000000000000001e+00 -1.2067713232602157e+01 2.8525136078719164e+00 2.7618235199017409e+00 1 0 0 +44 1 3 -1.0500000000000000e+00 8.3516959569061555e+00 -3.1339532310223461e-02 1.1357433570971924e+00 0 0 0 +45 1 3 -1.0500000000000000e+00 -1.1933025492148120e+01 2.7595329973670104e+00 1.1370134112483044e+00 1 0 0 +46 1 4 -9.4999999999999996e-01 6.0662672751172373e+00 1.5632462792111497e+00 1.0069655351602584e+00 0 0 0 +47 1 3 -1.0500000000000000e+00 4.7171183489904180e+00 3.5553451756140646e+00 3.2357682722939334e+00 0 0 0 +48 1 3 -1.0500000000000000e+00 -1.2179814839759992e+01 1.3781454091287202e+00 3.2374743626679336e+00 1 0 0 +49 1 3 -1.0500000000000000e+00 7.3067998243476922e+00 3.7041714141887212e+00 3.0459588478344077e+00 0 0 0 +50 1 5 4.2499999999999999e-01 5.5593955964411492e+00 6.8439387532284712e-01 1.1505669005138230e+00 0 0 0 +51 1 1 1.5750000000000000e+00 -1.0271831701454774e+01 5.9724606597474157e+00 -3.2705090813571758e-03 1 0 0 +52 1 2 2.1000000000000001e+00 5.9408180554345194e+00 4.3804006042748469e+00 2.7539659364818760e+00 0 0 0 +53 1 2 2.1000000000000001e+00 6.0204684195903440e+00 7.3353880878252973e+00 2.7618080745736791e+00 0 0 0 +54 1 3 -1.0500000000000000e+00 5.7998593359670885e+00 4.4515526262705585e+00 1.1357348262919498e+00 0 0 0 +55 1 3 -1.0500000000000000e+00 6.1551595276671165e+00 7.2424262028151780e+00 1.1369916832629752e+00 0 0 0 +56 1 4 -9.4999999999999996e-01 -1.1965495382161963e+01 6.0462304220183150e+00 1.0070022736298210e+00 1 0 0 +57 1 3 -1.0500000000000000e+00 7.3253562399943561e+00 8.0382687380075382e+00 3.2357743586474470e+00 0 0 0 +58 1 3 -1.0500000000000000e+00 5.9083487186442269e+00 5.8610518812341148e+00 3.2374617422859089e+00 0 0 0 +59 1 3 -1.0500000000000000e+00 4.7549501783979871e+00 8.1871270499566329e+00 3.0459460044387185e+00 0 0 0 +60 1 5 4.2499999999999999e-01 8.1675777506518017e+00 5.1673452186951785e+00 1.1508566812238072e+00 0 0 0 +61 1 1 1.5750000000000000e+00 7.7761138336528575e+00 7.4761697781487406e+00 -3.7580555383147640e-03 0 0 0 +62 1 2 2.1000000000000001e+00 6.9870625419908770e+00 1.0236857881965378e-01 -2.7609530688361730e+00 0 0 0 +63 1 2 2.1000000000000001e+00 6.9638163429426783e+00 6.1131999232440997e+00 -2.7688597574900182e+00 0 0 0 +64 1 3 -1.0500000000000000e+00 7.1845768042068343e+00 8.9971837243373898e+00 -1.1427811518142867e+00 0 0 0 +65 1 3 -1.0500000000000000e+00 6.8290823812761374e+00 6.2059099045834571e+00 -1.1439562764296625e+00 0 0 0 +66 1 4 -9.4999999999999996e-01 -1.1170087733372744e+01 7.4024835932118371e+00 -1.0139778639834489e+00 1 0 0 +67 1 3 -1.0500000000000000e+00 -9.8209500322774037e+00 5.4102853287564159e+00 -3.2425657088525419e+00 1 0 0 +68 1 3 -1.0500000000000000e+00 7.0761041543125955e+00 7.5875255489076068e+00 -3.2446577662945764e+00 0 0 0 +69 1 3 -1.0500000000000000e+00 8.2292664263953057e+00 5.2614600888460927e+00 -3.0529632035400311e+00 0 0 0 +70 1 5 4.2499999999999999e-01 -1.0663272694379867e+01 8.2812544466164262e+00 -1.1574899906021443e+00 1 0 0 +71 1 1 1.5750000000000000e+00 5.1679291867752841e+00 2.9932421670148486e+00 -3.7577228510699001e-03 0 0 0 +72 1 2 2.1000000000000001e+00 -1.1044767300168616e+01 4.5852760408334774e+00 -2.7609521778782176e+00 1 0 0 +73 1 2 2.1000000000000001e+00 -1.1124388980911734e+01 1.6303195608669299e+00 -2.7688431292616507e+00 1 0 0 +74 1 3 -1.0500000000000000e+00 -1.0903581498310636e+01 4.5142906934311924e+00 -1.1427845473335605e+00 1 0 0 +75 1 3 -1.0500000000000000e+00 -1.1259106369033972e+01 1.7230268384806458e+00 -1.1439410995923396e+00 1 0 0 +76 1 4 -9.4999999999999996e-01 6.8617144958469076e+00 2.9195557673048818e+00 -1.0139879262950160e+00 0 0 0 +77 1 3 -1.0500000000000000e+00 8.2108057946072996e+00 9.2735729230230390e-01 -3.2425776499777719e+00 0 0 0 +78 1 3 -1.0500000000000000e+00 -1.1012059810070339e+01 3.1045919471971004e+00 -3.2446473870783468e+00 1 0 0 +79 1 3 -1.0500000000000000e+00 -9.8588900558710808e+00 7.7850518566728155e-01 -3.0529472339342547e+00 1 0 0 +80 1 5 4.2499999999999999e-01 7.3685681396951637e+00 3.7983364769353116e+00 -1.1575475830507376e+00 0 0 0 +81 1 1 1.5750000000000000e+00 -7.7200137563852609e+00 1.4895294530661403e+00 -3.2684599822623284e-03 1 0 0 +82 1 2 2.1000000000000001e+00 -6.9309835694285180e+00 8.8633000360003891e+00 2.7539655829756615e+00 1 0 0 +83 1 2 2.1000000000000001e+00 -6.9077088390904287e+00 2.8524991867344269e+00 2.7618117534379607e+00 1 0 0 +84 1 3 -1.0500000000000000e+00 -7.1282896122357791e+00 -3.1337790666402299e-02 1.1357138609993100e+00 1 0 0 +85 1 3 -1.0500000000000000e+00 -6.7730290070254648e+00 2.7595293114608452e+00 1.1370158767616427e+00 1 0 0 +86 1 4 -9.4999999999999996e-01 -9.4137011727461637e+00 1.5632889909165790e+00 1.0069804405775873e+00 1 0 0 +87 1 3 -1.0500000000000000e+00 -1.0762886927889904e+01 3.5553424385566323e+00 3.2357631758371692e+00 1 0 0 +88 1 3 -1.0500000000000000e+00 -7.0198114225359447e+00 1.3781627149599167e+00 3.2374581287983730e+00 1 0 0 +89 1 3 -1.0500000000000000e+00 -8.1732123893871496e+00 3.7041758941777481e+00 3.0459624211456457e+00 1 0 0 +90 1 5 4.2499999999999999e-01 -9.9205899642595909e+00 6.8440357171864363e-01 1.1507119739579768e+00 1 0 0 +91 1 1 1.5750000000000000e+00 -5.1118389155552801e+00 5.9724604992986876e+00 -3.2677938051328681e-03 1 0 0 +92 1 2 2.1000000000000001e+00 -9.5391764189832653e+00 4.3803869998831004e+00 2.7539574271080607e+00 1 0 0 +93 1 2 2.1000000000000001e+00 -9.4595081799096388e+00 7.3353965025317827e+00 2.7618078347600434e+00 1 0 0 +94 1 3 -1.0500000000000000e+00 -9.6801468113930103e+00 4.4515564521540760e+00 1.1357496055372582e+00 1 0 0 +95 1 3 -1.0500000000000000e+00 -9.3248381172301720e+00 7.2424157374410534e+00 1.1369982830380732e+00 1 0 0 +96 1 4 -9.4999999999999996e-01 -6.8054892996665686e+00 6.0462398159612256e+00 1.0069818364520042e+00 1 0 0 +97 1 3 -1.0500000000000000e+00 -8.1546879688645451e+00 8.0382456007117398e+00 3.2357858485300515e+00 1 0 0 +98 1 3 -1.0500000000000000e+00 -9.5716494128412961e+00 5.8610801354623092e+00 3.2374551881368738e+00 1 0 0 +99 1 3 -1.0500000000000000e+00 -1.0725043969209066e+01 8.1871237437456550e+00 3.0459446329304463e+00 1 0 0 +100 1 5 4.2499999999999999e-01 -7.3124574315238666e+00 5.1673091520186851e+00 1.1507497875855961e+00 1 0 0 +101 1 1 1.5750000000000000e+00 -7.7038948864236607e+00 7.4761709779946877e+00 -3.7563858194751276e-03 1 0 0 +102 1 2 2.1000000000000001e+00 -8.4929416250579237e+00 1.0238205190912097e-01 -2.7609433628825437e+00 1 0 0 +103 1 2 2.1000000000000001e+00 -8.5162068339533832e+00 6.1131914931820752e+00 -2.7688610988552806e+00 1 0 0 +104 1 3 -1.0500000000000000e+00 -8.2954155113210621e+00 8.9971804574221004e+00 -1.1427988389805961e+00 1 0 0 +105 1 3 -1.0500000000000000e+00 -8.6509205149498847e+00 6.2059203624978956e+00 -1.1439628590241284e+00 1 0 0 +106 1 4 -9.4999999999999996e-01 -6.0100779546322549e+00 7.4024979040990928e+00 -1.0139958673379255e+00 1 0 0 +107 1 3 -1.0500000000000000e+00 -4.6609961845666854e+00 5.4102617087963587e+00 -3.2425544229802377e+00 1 0 0 +108 1 3 -1.0500000000000000e+00 -8.4038980403496684e+00 7.5874972699614922e+00 -3.2446537367483241e+00 1 0 0 +109 1 3 -1.0500000000000000e+00 -7.2507418722833936e+00 5.2614645688107124e+00 -3.0529610822747220e+00 1 0 0 +110 1 5 4.2499999999999999e-01 -5.5033059365206407e+00 8.2812208311420328e+00 -1.1575765233774842e+00 1 0 0 +111 1 1 1.5750000000000000e+00 -1.0312056810203035e+01 2.9932322130065998e+00 -3.7546907983969646e-03 1 0 0 +112 1 2 2.1000000000000001e+00 -5.8847433874873287e+00 4.5852785579583113e+00 -2.7609429033193313e+00 1 0 0 +113 1 2 2.1000000000000001e+00 -5.9643839170466686e+00 1.6303066689684940e+00 -2.7688547216593093e+00 1 0 0 +114 1 3 -1.0500000000000000e+00 -5.7435669944029248e+00 4.5142929050558713e+00 -1.1428123357037983e+00 1 0 0 +115 1 3 -1.0500000000000000e+00 -6.0991091928443781e+00 1.7230226164423819e+00 -1.1439386957606192e+00 1 0 0 +116 1 4 -9.4999999999999996e-01 -8.6183165743253909e+00 2.9195138811823007e+00 -1.0140048055866231e+00 1 0 0 +117 1 3 -1.0500000000000000e+00 -7.2691903819614820e+00 9.2736020008046438e-01 -3.2425717834672385e+00 1 0 0 +118 1 3 -1.0500000000000000e+00 -5.8520558193569849e+00 3.1046084246173429e+00 -3.2446638893543165e+00 1 0 0 +119 1 3 -1.0500000000000000e+00 -4.6989020453283867e+00 7.7850970320779922e-01 -3.0529439927969300e+00 1 0 0 +120 1 5 4.2499999999999999e-01 -8.1114486366180678e+00 3.7983239523822867e+00 -1.1577012407700238e+00 1 0 0 +121 1 1 1.5750000000000000e+00 -2.5599994626479976e+00 1.4895195225863134e+00 -3.2660642944506435e-03 1 0 0 +122 1 2 2.1000000000000001e+00 -1.7710062286867227e+00 8.8632972747936982e+00 2.7539546373495405e+00 1 0 0 +123 1 2 2.1000000000000001e+00 -1.7477123009753157e+00 2.8525136185930755e+00 2.7618236550482624e+00 1 0 0 +124 1 3 -1.0500000000000000e+00 -1.9683041681687321e+00 -3.1339314943114260e-02 1.1357434005060227e+00 1 0 0 +125 1 3 -1.0500000000000000e+00 -1.6130256197699246e+00 2.7595328394810750e+00 1.1370135266718489e+00 1 0 0 +126 1 4 -9.4999999999999996e-01 -4.2537337856944379e+00 1.5632441680250189e+00 1.0069648786930525e+00 1 0 0 +127 1 3 -1.0500000000000000e+00 -5.6028806915798572e+00 3.5553457721911457e+00 3.2357688590305571e+00 1 0 0 +128 1 3 -1.0500000000000000e+00 -1.8598151617417997e+00 1.3781457768821710e+00 3.2374742127375917e+00 1 0 0 +129 1 3 -1.0500000000000000e+00 -3.0132009706882785e+00 3.7041715558434340e+00 3.0459588995882712e+00 1 0 0 +130 1 5 4.2499999999999999e-01 -4.7606046035337171e+00 6.8439349642540748e-01 1.1505607409996657e+00 1 0 0 +131 1 1 1.5750000000000000e+00 4.8168369057153271e-02 5.9724605712145085e+00 -3.2704117388746567e-03 1 0 0 +132 1 2 2.1000000000000001e+00 -4.3791817898634946e+00 4.3804013865484848e+00 2.7539658968809935e+00 1 0 0 +133 1 2 2.1000000000000001e+00 -4.2995319515097883e+00 7.3353882982958218e+00 2.7618078686262244e+00 1 0 0 +134 1 3 -1.0500000000000000e+00 -4.5201407292494871e+00 4.4515523522287275e+00 1.1357346289073345e+00 1 0 0 +135 1 3 -1.0500000000000000e+00 -4.1648406595123815e+00 7.2424265294413708e+00 1.1369912415882819e+00 1 0 0 +136 1 4 -9.4999999999999996e-01 -1.6454953945829232e+00 6.0462304571223804e+00 1.0070026477177905e+00 1 0 0 +137 1 3 -1.0500000000000000e+00 -2.9946439468920527e+00 8.0382690637231917e+00 3.2357743104080114e+00 1 0 0 +138 1 3 -1.0500000000000000e+00 -4.4116515205365854e+00 5.8610507068010520e+00 3.2374621599322246e+00 1 0 0 +139 1 3 -1.0500000000000000e+00 -5.5650494733788616e+00 8.1871266439263444e+00 3.0459458790032787e+00 1 0 0 +140 1 5 4.2499999999999999e-01 -2.1524218145509142e+00 5.1673462038601450e+00 1.1508591924041909e+00 1 0 0 +141 1 1 1.5750000000000000e+00 -2.5438859347542353e+00 7.4761697245415135e+00 -3.7582632092334478e-03 1 0 0 +142 1 2 2.1000000000000001e+00 -3.3329363804842851e+00 1.0236811376637078e-01 -2.7609530240071400e+00 1 0 0 +143 1 2 2.1000000000000001e+00 -3.3561829873008966e+00 6.1132000526679882e+00 -2.7688597295862918e+00 1 0 0 +144 1 3 -1.0500000000000000e+00 -3.1354235356298261e+00 8.9971842040066932e+00 -1.1427807792040543e+00 1 0 0 +145 1 3 -1.0500000000000000e+00 -3.4909182600583835e+00 6.2059094368932080e+00 -1.1439561958179105e+00 1 0 0 +146 1 4 -9.4999999999999996e-01 -8.5008735848989936e-01 7.4024836920448358e+00 -1.0139778123793981e+00 1 0 0 +147 1 3 -1.0500000000000000e+00 4.9904929440264922e-01 5.4102852955378324e+00 -3.2425656000684357e+00 1 0 0 +148 1 3 -1.0500000000000000e+00 -3.2438965163198175e+00 7.5875255784303768e+00 -3.2446584652783006e+00 1 0 0 +149 1 3 -1.0500000000000000e+00 -2.0907332304654513e+00 5.2614599131077355e+00 -3.0529635108663689e+00 1 0 0 +150 1 5 4.2499999999999999e-01 -3.4327252441785028e-01 8.2812545429943718e+00 -1.1574891817763771e+00 1 0 0 +151 1 1 1.5750000000000000e+00 -5.1520707526539180e+00 2.9932422696247407e+00 -3.7575710303681120e-03 1 0 0 +152 1 2 2.1000000000000001e+00 -7.2476725112305829e-01 4.5852758198773422e+00 -2.7609523624229535e+00 1 0 0 +153 1 2 2.1000000000000001e+00 -8.0438924000571177e-01 1.6303201218117742e+00 -2.7688428916587142e+00 1 0 0 +154 1 3 -1.0500000000000000e+00 -5.8358168128787469e-01 4.5142909571471250e+00 -1.1427842365077652e+00 1 0 0 +155 1 3 -1.0500000000000000e+00 -9.3910616162538574e-01 1.7230269705662700e+00 -1.1439410014752056e+00 1 0 0 +156 1 4 -9.4999999999999996e-01 -3.4582854395786136e+00 2.9195566902968508e+00 -1.0139875801681342e+00 1 0 0 +157 1 3 -1.0500000000000000e+00 -2.1091939503703152e+00 9.2735770730401157e-01 -3.2425784113786129e+00 1 0 0 +158 1 3 -1.0500000000000000e+00 -6.9205988720759315e-01 3.1045918731948028e+00 -3.2446474792644775e+00 1 0 0 +159 1 3 -1.0500000000000000e+00 4.6110929925033162e-01 7.7850537414041909e-01 -3.0529474813034367e+00 1 0 0 +160 1 5 4.2499999999999999e-01 -2.9514312473451580e+00 3.7983374737998545e+00 -1.1575435527823981e+00 1 0 0 +161 1 1 1.5750000000000000e+00 2.6563134001835174e+00 1.0455371516328153e+01 -3.2734775751421807e-03 0 0 0 +162 1 2 2.1000000000000001e+00 3.2200000793507915e+00 -1.8034168055802969e+01 2.7539699954278376e+00 0 1 0 +163 1 2 2.1000000000000001e+00 3.4686304351053021e+00 1.1818330371923647e+01 2.7618152520441335e+00 0 0 0 +164 1 3 -1.0500000000000000e+00 3.2480341177807297e+00 8.9344903893301542e+00 1.1357344410643542e+00 0 0 0 +165 1 3 -1.0500000000000000e+00 3.6033098122302398e+00 1.1725346434065575e+01 1.1370112044265888e+00 0 0 0 +166 1 4 -9.4999999999999996e-01 9.6267397491767959e-01 1.0529174885771052e+01 1.0070252189892397e+00 0 0 0 +167 1 3 -1.0500000000000000e+00 -3.8653877399151604e-01 1.2521163438190538e+01 3.2357641403694473e+00 0 0 0 +168 1 3 -1.0500000000000000e+00 3.3565301561723722e+00 1.0343985356367806e+01 3.2374269175278840e+00 0 0 0 +169 1 3 -1.0500000000000000e+00 2.2031200709181498e+00 1.2669998832466721e+01 3.0459640112402759e+00 0 0 0 +170 1 5 4.2499999999999999e-01 4.5576637197079073e-01 9.6503202047150296e+00 1.1510612204759685e+00 0 0 0 +171 1 1 1.5750000000000000e+00 5.2644962792255114e+00 1.4938261534530948e+01 -3.2647451325473753e-03 0 0 0 +172 1 2 2.1000000000000001e+00 8.3716356417033211e-01 1.3346218268802954e+01 2.7539470758802835e+00 0 0 0 +173 1 2 2.1000000000000001e+00 9.1681075011299562e-01 1.6301231345167661e+01 2.7618125766893566e+00 0 0 0 +174 1 3 -1.0500000000000000e+00 6.9620077398076852e-01 1.3417388047104328e+01 1.1357329589097631e+00 0 0 0 +175 1 3 -1.0500000000000000e+00 1.0514831822196271e+00 1.6208254021374852e+01 1.1370122634561355e+00 0 0 0 +176 1 4 -9.4999999999999996e-01 3.5707945950799811e+00 1.5012003258438757e+01 1.0069522165247839e+00 0 0 0 +177 1 3 -1.0500000000000000e+00 2.2216102376958187e+00 1.7004067428805609e+01 3.2357767642373751e+00 0 0 0 +178 1 3 -1.0500000000000000e+00 8.0468569905412757e-01 1.4826903246577299e+01 3.2374729366625967e+00 0 0 0 +179 1 3 -1.0500000000000000e+00 -3.4870265184444982e-01 1.7152922875565228e+01 3.0459529855636607e+00 0 0 0 +180 1 5 4.2499999999999999e-01 3.0638743761134464e+00 1.4133083814238685e+01 1.1505085237616779e+00 0 0 0 +181 1 1 1.5750000000000000e+00 2.6724321383913008e+00 1.6441984484756983e+01 -3.7572437476853793e-03 0 0 0 +182 1 2 2.1000000000000001e+00 1.8833962660382699e+00 9.0681931419489921e+00 -2.7609335407081872e+00 0 0 0 +183 1 2 2.1000000000000001e+00 1.8601111196809121e+00 1.5079040342628350e+01 -2.7688508235497418e+00 0 0 0 +184 1 3 -1.0500000000000000e+00 1.8555857070306878e+00 -1.7900270605410917e+01 -1.1427969927137482e+00 0 1 0 +185 1 3 -1.0500000000000000e+00 1.7253995479611604e+00 1.5171757634659638e+01 -1.1439490826924779e+00 0 0 0 +186 1 4 -9.4999999999999996e-01 4.3662322107158733e+00 1.6368309943641055e+01 -1.0139855229210077e+00 0 0 0 +187 1 3 -1.0500000000000000e+00 5.7153027190516923e+00 1.4376080986155142e+01 -3.2425652845281192e+00 0 0 0 +188 1 3 -1.0500000000000000e+00 1.9724442262540727e+00 1.6553320295057897e+01 -3.2446645540223695e+00 0 0 0 +189 1 3 -1.0500000000000000e+00 3.1255993997228746e+00 1.4227253671506265e+01 -3.0529479201541534e+00 0 0 0 +190 1 5 4.2499999999999999e-01 4.8730503872703981e+00 1.7247084738816252e+01 -1.1575108950696489e+00 0 0 0 +191 1 1 1.5750000000000000e+00 6.4287605771619738e-02 1.1959047499133955e+01 -3.7503865813821591e-03 0 0 0 +192 1 2 2.1000000000000001e+00 4.4915804029907438e+00 1.3551111831722395e+01 -2.7609471625592663e+00 0 0 0 +193 1 2 2.1000000000000001e+00 4.4119577432399595e+00 1.0596109686747351e+01 -2.7688628659227765e+00 0 0 0 +194 1 3 -1.0500000000000000e+00 4.6327720860930999e+00 1.3480101674103746e+01 -1.1428277031521787e+00 0 0 0 +195 1 3 -1.0500000000000000e+00 4.2772319797087590e+00 1.0688840900034439e+01 -1.1439426903633443e+00 0 0 0 +196 1 4 -9.4999999999999996e-01 1.7580042741312081e+00 1.1885300143491271e+01 -1.0140430923412715e+00 0 0 0 +197 1 3 -1.0500000000000000e+00 3.1071547577327969e+00 9.8931852268420180e+00 -3.2425655357851380e+00 0 0 0 +198 1 3 -1.0500000000000000e+00 4.5242699949370255e+00 1.2070431784027537e+01 -3.2446352562949325e+00 0 0 0 +199 1 3 -1.0500000000000000e+00 5.6774301856846563e+00 9.7443531193086770e+00 -3.0529533590117293e+00 0 0 0 +200 1 5 4.2499999999999999e-01 2.2648570458734767e+00 1.2764054876209290e+01 -1.1579888107521015e+00 0 0 0 +201 1 1 1.5750000000000000e+00 7.8163274667709004e+00 1.0455361822489916e+01 -3.2709891462765484e-03 0 0 0 +202 1 2 2.1000000000000001e+00 -1.2260022563792901e+01 -1.8034171036451074e+01 2.7539593838063130e+00 1 1 0 +203 1 2 2.1000000000000001e+00 -1.2011372927310228e+01 1.1818343457748362e+01 2.7618265468659775e+00 1 0 0 +204 1 3 -1.0500000000000000e+00 8.4080197705526096e+00 8.9344884845612391e+00 1.1357635616008466e+00 0 0 0 +205 1 3 -1.0500000000000000e+00 -1.1876687672220676e+01 1.1725350016313566e+01 1.1370089651291622e+00 1 0 0 +206 1 4 -9.4999999999999996e-01 6.1226432401957958e+00 1.0529133102795765e+01 1.0070115060204152e+00 0 0 0 +207 1 3 -1.0500000000000000e+00 4.7734668544665446e+00 1.2521166817291366e+01 3.2357690806651949e+00 0 0 0 +208 1 3 -1.0500000000000000e+00 -1.2123474030539958e+01 1.0343970332896109e+01 3.2374431734477387e+00 1 0 0 +209 1 3 -1.0500000000000000e+00 7.3631314638252157e+00 1.2669994182427597e+01 3.0459606244004132e+00 0 0 0 +210 1 5 4.2499999999999999e-01 5.6157533562485771e+00 9.6503133176461908e+00 1.1509245775060091e+00 0 0 0 +211 1 1 1.5750000000000000e+00 -1.0215496529349888e+01 1.4938261423331294e+01 -3.2671984669594423e-03 1 0 0 +212 1 2 2.1000000000000001e+00 5.9971582839890871e+00 1.3346232288807276e+01 2.7539563176022028e+00 0 0 0 +213 1 2 2.1000000000000001e+00 6.0767870017495582e+00 1.6301224009304729e+01 2.7618126124878195e+00 0 0 0 +214 1 3 -1.0500000000000000e+00 5.8562070155499164e+00 1.3417384395333375e+01 1.1357183501401593e+00 0 0 0 +215 1 3 -1.0500000000000000e+00 6.2114804261402661e+00 1.6208264386955651e+01 1.1370050309136168e+00 0 0 0 +216 1 4 -9.4999999999999996e-01 -1.1909211620817819e+01 1.5011994029862020e+01 1.0069718593232118e+00 1 0 0 +217 1 3 -1.0500000000000000e+00 7.3816555131360566e+00 1.7004091118074196e+01 3.2357656756583246e+00 0 0 0 +218 1 3 -1.0500000000000000e+00 5.9646835115051537e+00 1.4826873453180109e+01 3.2374785589618078e+00 0 0 0 +219 1 3 -1.0500000000000000e+00 4.8112906275483347e+00 1.7152926240598543e+01 3.0459544088802879e+00 0 0 0 +220 1 5 4.2499999999999999e-01 8.2239086021434531e+00 1.4133118218483940e+01 1.1506108499324537e+00 0 0 0 +221 1 1 1.5750000000000000e+00 7.8324408920161304e+00 1.6441983610717937e+01 -3.7594297909890884e-03 0 0 0 +222 1 2 2.1000000000000001e+00 7.0433997235143551e+00 9.0681792148270475e+00 -2.7609433793505778e+00 0 0 0 +223 1 2 2.1000000000000001e+00 7.0201340001296231e+00 1.5079048983075904e+01 -2.7688496626705303e+00 0 0 0 +224 1 3 -1.0500000000000000e+00 7.0155782305852874e+00 -1.7900266980861765e+01 -1.1427797504921990e+00 0 1 0 +225 1 3 -1.0500000000000000e+00 6.8854016068099639e+00 1.5171747073972536e+01 -1.1439426401780413e+00 0 0 0 +226 1 4 -9.4999999999999996e-01 -1.1113777147342798e+01 1.6368296182520734e+01 -1.0139673644246923e+00 1 0 0 +227 1 3 -1.0500000000000000e+00 -9.7646511702758900e+00 1.4376104836232383e+01 -3.2425769131107307e+00 1 0 0 +228 1 3 -1.0500000000000000e+00 7.1324461842806457e+00 1.6553349104877181e+01 -3.2446699530389926e+00 0 0 0 +229 1 3 -1.0500000000000000e+00 8.2856077950535507e+00 1.4227248777578755e+01 -3.0529496330623935e+00 0 0 0 +230 1 5 4.2499999999999999e-01 -1.0606916142948355e+01 1.7247118324243235e+01 -1.1574224546860155e+00 1 0 0 +231 1 1 1.5750000000000000e+00 5.2242739244354812e+00 1.1959056994618571e+01 -3.7532727914637576e-03 0 0 0 +232 1 2 2.1000000000000001e+00 -1.0988443129796577e+01 1.3551110560593809e+01 -2.7609569176995983e+00 1 0 0 +233 1 2 2.1000000000000001e+00 -1.1068048695702130e+01 1.0596121856381689e+01 -2.7688513474828484e+00 1 0 0 +234 1 3 -1.0500000000000000e+00 -1.0847241951081806e+01 1.3480099061382369e+01 -1.1428004053747500e+00 1 0 0 +235 1 3 -1.0500000000000000e+00 -1.1202765363241992e+01 1.0688845693686350e+01 -1.1439459591196393e+00 1 0 0 +236 1 4 -9.4999999999999996e-01 6.9180337353417016e+00 1.1885339729941098e+01 -1.0140270633946198e+00 0 0 0 +237 1 3 -1.0500000000000000e+00 8.2671524098729279e+00 9.8931836876833437e+00 -3.2425721304984254e+00 0 0 0 +238 1 3 -1.0500000000000000e+00 -1.0955734208517388e+01 1.2070414566453039e+01 -3.2446182476609398e+00 1 0 0 +239 1 3 -1.0500000000000000e+00 -9.8025577056732693e+00 9.7443480474548068e+00 -3.0529560570682035e+00 1 0 0 +240 1 5 4.2499999999999999e-01 7.4248734752605259e+00 1.2764066295177155e+01 -1.1578424655573620e+00 0 0 0 +241 1 1 1.5750000000000000e+00 -7.6636863980105723e+00 1.0455371549550875e+01 -3.2736966669304479e-03 1 0 0 +242 1 2 2.1000000000000001e+00 -7.0999990710355192e+00 -1.8034168111282145e+01 2.7539701102788019e+00 1 1 0 +243 1 2 2.1000000000000001e+00 -6.8513690426892451e+00 1.1818330417854160e+01 2.7618149786464521e+00 1 0 0 +244 1 3 -1.0500000000000000e+00 -7.0719662711101812e+00 8.9344903042783628e+00 1.1357345069924225e+00 1 0 0 +245 1 3 -1.0500000000000000e+00 -6.7166907540342233e+00 1.1725346382842613e+01 1.1370110473100272e+00 1 0 0 +246 1 4 -9.4999999999999996e-01 -9.3573260672622727e+00 1.0529174208841528e+01 1.0070252131964725e+00 1 0 0 +247 1 3 -1.0500000000000000e+00 -1.0706539610507846e+01 1.2521163280396088e+01 3.2357640814962956e+00 1 0 0 +248 1 3 -1.0500000000000000e+00 -6.9634703631137729e+00 1.0343985091037393e+01 3.2374266804707119e+00 1 0 0 +249 1 3 -1.0500000000000000e+00 -8.1168803339350379e+00 1.2669999097078030e+01 3.0459638003843619e+00 1 0 0 +250 1 5 4.2499999999999999e-01 -9.8642334722321223e+00 9.6503204443188402e+00 1.1510602007101145e+00 1 0 0 +251 1 1 1.5750000000000000e+00 -5.0555038517207738e+00 1.4938261738890343e+01 -3.2644360310367659e-03 1 0 0 +252 1 2 2.1000000000000001e+00 -9.4828364774811842e+00 1.3346217905042987e+01 2.7539473478098913e+00 1 0 0 +253 1 2 2.1000000000000001e+00 -9.4031892666074217e+00 1.6301231779632818e+01 2.7618124621169056e+00 1 0 0 +254 1 3 -1.0500000000000000e+00 -9.6237991655729793e+00 1.3417388438033317e+01 1.1357331457960171e+00 1 0 0 +255 1 3 -1.0500000000000000e+00 -9.2685168345328872e+00 1.6208253547145770e+01 1.1370123846061553e+00 1 0 0 +256 1 4 -9.4999999999999996e-01 -6.7492056915652885e+00 1.5012003321026935e+01 1.0069523554452928e+00 1 0 0 +257 1 3 -1.0500000000000000e+00 -8.0983893100633519e+00 1.7004067932473877e+01 3.2357766175726148e+00 1 0 0 +258 1 3 -1.0500000000000000e+00 -9.5153144179962954e+00 1.4826903279627327e+01 3.2374724255443947e+00 1 0 0 +259 1 3 -1.0500000000000000e+00 -1.0668703168553188e+01 1.7152922672989472e+01 3.0459531606477839e+00 1 0 0 +260 1 5 4.2499999999999999e-01 -7.2561252036506980e+00 1.4133084321951994e+01 1.1505098705128987e+00 1 0 0 +261 1 1 1.5750000000000000e+00 -7.6475676736905971e+00 1.6441984614323157e+01 -3.7576410911643876e-03 1 0 0 +262 1 2 2.1000000000000001e+00 -8.4366040275132406e+00 9.0681930278031473e+00 -2.7609335500569747e+00 1 0 0 +263 1 2 2.1000000000000001e+00 -8.4598890146513455e+00 1.5079040601080134e+01 -2.7688510489233167e+00 1 0 0 +264 1 3 -1.0500000000000000e+00 -8.4644143079304612e+00 -1.7900269957740477e+01 -1.1427967775321957e+00 1 1 0 +265 1 3 -1.0500000000000000e+00 -8.5946007116663132e+00 1.5171756827133724e+01 -1.1439485975510628e+00 1 0 0 +266 1 4 -9.4999999999999996e-01 -5.9537679681653151e+00 1.6368309168283670e+01 -1.0139856989316165e+00 1 0 0 +267 1 3 -1.0500000000000000e+00 -4.6046964494860898e+00 1.4376081286353607e+01 -3.2425649205705174e+00 1 0 0 +268 1 3 -1.0500000000000000e+00 -8.3475558754399124e+00 1.6553320859356912e+01 -3.2446655570405536e+00 1 0 0 +269 1 3 -1.0500000000000000e+00 -7.1944009052872069e+00 1.4227253415250768e+01 -3.0529479683150100e+00 1 0 0 +270 1 5 4.2499999999999999e-01 -5.4469496542482680e+00 1.7247084860834857e+01 -1.1575125267203532e+00 1 0 0 +271 1 1 1.5750000000000000e+00 -1.0255712633101528e+01 1.1959047249232842e+01 -3.7503693590110743e-03 1 0 0 +272 1 2 2.1000000000000001e+00 -5.8284201346147073e+00 1.3551112633249122e+01 -2.7609471419709433e+00 1 0 0 +273 1 2 2.1000000000000001e+00 -5.9080424941932153e+00 1.0596109220690689e+01 -2.7688628072186683e+00 1 0 0 +274 1 3 -1.0500000000000000e+00 -5.6872277599586996e+00 1.3480101435889090e+01 -1.1428283866518854e+00 1 0 0 +275 1 3 -1.0500000000000000e+00 -6.0427680579917293e+00 1.0688841214141384e+01 -1.1439433517717656e+00 1 0 0 +276 1 4 -9.4999999999999996e-01 -8.5619959665734147e+00 1.1885299915121873e+01 -1.0140429279795615e+00 1 0 0 +277 1 3 -1.0500000000000000e+00 -7.2128453343082271e+00 9.8931855774587198e+00 -3.2425657643378525e+00 1 0 0 +278 1 3 -1.0500000000000000e+00 -5.7957299312633053e+00 1.2070431551626321e+01 -3.2446350249445235e+00 1 0 0 +279 1 3 -1.0500000000000000e+00 -4.6425695661462196e+00 9.7443530477275679e+00 -3.0529532196506795e+00 1 0 0 +280 1 5 4.2499999999999999e-01 -8.0551425673563894e+00 1.2764055666864170e+01 -1.1579876909028854e+00 1 0 0 +281 1 1 1.5750000000000000e+00 -2.5036724751688171e+00 1.0455361759083811e+01 -3.2712711680531470e-03 1 0 0 +282 1 2 2.1000000000000001e+00 -1.9400228605798482e+00 -1.8034171454532189e+01 2.7539596865588258e+00 1 1 0 +283 1 2 2.1000000000000001e+00 -1.6913729123417731e+00 1.1818343618664318e+01 2.7618267327017616e+00 1 0 0 +284 1 3 -1.0500000000000000e+00 -1.9119803931372488e+00 8.9344892347650671e+00 1.1357639880848378e+00 1 0 0 +285 1 3 -1.0500000000000000e+00 -1.5566878690749917e+00 1.1725349553088837e+01 1.1370088549317554e+00 1 0 0 +286 1 4 -9.4999999999999996e-01 -4.1973568501655052e+00 1.0529132534062505e+01 1.0070110973834296e+00 1 0 0 +287 1 3 -1.0500000000000000e+00 -5.5465318119038987e+00 1.2521167504631986e+01 3.2357693370264009e+00 1 0 0 +288 1 3 -1.0500000000000000e+00 -1.8034741996403554e+00 1.0343970336471010e+01 3.2374423050401600e+00 1 0 0 +289 1 3 -1.0500000000000000e+00 -2.9568695567301644e+00 1.2669994183537906e+01 3.0459605033388062e+00 1 0 0 +290 1 5 4.2499999999999999e-01 -4.7042469088330439e+00 9.6503130783144044e+00 1.1509221001927727e+00 1 0 0 +291 1 1 1.5750000000000000e+00 1.0450346973463098e-01 1.4938261236297333e+01 -3.2670506730401172e-03 1 0 0 +292 1 2 2.1000000000000001e+00 -4.3228420481760716e+00 1.3346232732007316e+01 2.7539563932159634e+00 1 0 0 +293 1 2 2.1000000000000001e+00 -4.2432134692497367e+00 1.6301223752354527e+01 2.7618123881160574e+00 1 0 0 +294 1 3 -1.0500000000000000e+00 -4.4637927327409024e+00 1.3417383967610970e+01 1.1357180288639768e+00 1 0 0 +295 1 3 -1.0500000000000000e+00 -4.1085196585471646e+00 1.6208264626532635e+01 1.1370043708840640e+00 1 0 0 +296 1 4 -9.4999999999999996e-01 -1.5892118927513685e+00 1.5011993465855195e+01 1.0069717418888526e+00 1 0 0 +297 1 3 -1.0500000000000000e+00 -2.9383445989094135e+00 1.7004091419961096e+01 3.2357659595260095e+00 1 0 0 +298 1 3 -1.0500000000000000e+00 -4.3553166601485476e+00 1.4826873197424877e+01 3.2374790045700852e+00 1 0 0 +299 1 3 -1.0500000000000000e+00 -5.5087090978359239e+00 1.7152925908147093e+01 3.0459546197474001e+00 1 0 0 +300 1 5 4.2499999999999999e-01 -2.0960913924612612e+00 1.4133118310388799e+01 1.1506099517336104e+00 1 0 0 +301 1 1 1.5750000000000000e+00 -2.4875591017952310e+00 1.6441983631942183e+01 -3.7595151500315893e-03 1 0 0 +302 1 2 2.1000000000000001e+00 -3.2765996605939858e+00 9.0681789268622346e+00 -2.7609433563661456e+00 1 0 0 +303 1 2 2.1000000000000001e+00 -3.2998653023383682e+00 1.5079049184116290e+01 -2.7688496671533649e+00 1 0 0 +304 1 3 -1.0500000000000000e+00 -3.3044219890671753e+00 -1.7900266681096994e+01 -1.1427795585717835e+00 1 1 0 +305 1 3 -1.0500000000000000e+00 -3.4345989454937165e+00 1.5171746655803712e+01 -1.1439426919442308e+00 1 0 0 +306 1 4 -9.4999999999999996e-01 -7.9377665672300779e-01 1.6368296633100169e+01 -1.0139672617067319e+00 1 0 0 +307 1 3 -1.0500000000000000e+00 5.5534868438584084e-01 1.4376105151954103e+01 -3.2425775178456107e+00 1 0 0 +308 1 3 -1.0500000000000000e+00 -3.1875541544200496e+00 1.6553349368867583e+01 -3.2446705490554963e+00 1 0 0 +309 1 3 -1.0500000000000000e+00 -2.0343923260202423e+00 1.4227248534036743e+01 -3.0529497284009599e+00 1 0 0 +310 1 5 4.2499999999999999e-01 -2.8691619587030104e-01 1.7247118382062236e+01 -1.1574212565794415e+00 1 0 0 +311 1 1 1.5750000000000000e+00 -5.0957261453677205e+00 1.1959057139099524e+01 -3.7531547867057924e-03 1 0 0 +312 1 2 2.1000000000000001e+00 -6.6844354483350799e-01 1.3551110266998439e+01 -2.7609568234960040e+00 1 0 0 +313 1 2 2.1000000000000001e+00 -7.4804896223840167e-01 1.0596122230984061e+01 -2.7688515273933572e+00 1 0 0 +314 1 3 -1.0500000000000000e+00 -5.2724202123535946e-01 1.3480098969688658e+01 -1.1428001598979964e+00 1 0 0 +315 1 3 -1.0500000000000000e+00 -8.8276536122547178e-01 1.0688845631800483e+01 -1.1439460002810460e+00 1 0 0 +316 1 4 -9.4999999999999996e-01 -3.4019662726515918e+00 1.1885340094739142e+01 -1.0140272109664838e+00 1 0 0 +317 1 3 -1.0500000000000000e+00 -2.0528473081502625e+00 9.8931841810449264e+00 -3.2425722407459503e+00 1 0 0 +318 1 3 -1.0500000000000000e+00 -6.3573424619330154e-01 1.2070414396821146e+01 -3.2446180957081046e+00 1 0 0 +319 1 3 -1.0500000000000000e+00 5.1744185669619647e-01 9.7443480289127145e+00 -3.0529559039522471e+00 1 0 0 +320 1 5 4.2499999999999999e-01 -2.8951265260920414e+00 1.2764066156472012e+01 -1.1578424373010439e+00 1 0 0 +321 1 1 1.5750000000000000e+00 2.4873158312812595e+00 -1.6442085140542702e+01 -3.2731044767775330e-03 0 1 0 +322 1 2 2.1000000000000001e+00 3.2763303149493339e+00 -9.0683326576281793e+00 2.7539613504973826e+00 0 1 0 +323 1 2 2.1000000000000001e+00 3.2996440062323522e+00 -1.5079163855001152e+01 2.7618052351303000e+00 0 1 0 +324 1 3 -1.0500000000000000e+00 3.0790227247234743e+00 -1.7962996900519780e+01 1.1357369105052264e+00 0 1 0 +325 1 3 -1.0500000000000000e+00 3.4343217071143606e+00 -1.5172137633996615e+01 1.1369964612814574e+00 0 1 0 +326 1 4 -9.4999999999999996e-01 7.9370044014982000e-01 -1.6368273971208470e+01 1.0070225988534567e+00 0 1 0 +327 1 3 -1.0500000000000000e+00 -5.5550646979719431e-01 -1.4376303482612908e+01 3.2357750050409617e+00 0 1 0 +328 1 3 -1.0500000000000000e+00 3.1875194117149164e+00 -1.6553483052839894e+01 3.2374345381514082e+00 0 1 0 +329 1 3 -1.0500000000000000e+00 2.0341105779595932e+00 -1.4227436497588396e+01 3.0459506035312476e+00 0 1 0 +330 1 5 4.2499999999999999e-01 2.8674517218617801e-01 -1.7247173634562643e+01 1.1510526978509290e+00 0 1 0 +331 1 1 1.5750000000000000e+00 5.0954822332712713e+00 -1.1959202907500007e+01 -3.2689027687062833e-03 0 1 0 +332 1 2 2.1000000000000001e+00 6.6817149298760725e-01 -1.3551259854316488e+01 2.7539499370113383e+00 0 1 0 +333 1 2 2.1000000000000001e+00 7.4779844304577914e-01 -1.0596215429331199e+01 2.7618213942130811e+00 0 1 0 +334 1 3 -1.0500000000000000e+00 5.2719372455953284e-01 -1.3480064946544015e+01 1.1357459580603049e+00 0 1 0 +335 1 3 -1.0500000000000000e+00 8.8247034442780148e-01 -1.0689208474290135e+01 1.1370185048637591e+00 0 1 0 +336 1 4 -9.4999999999999996e-01 3.4017986335829793e+00 -1.1885434663339312e+01 1.0069865452366784e+00 0 1 0 +337 1 3 -1.0500000000000000e+00 2.0525899417440829e+00 -9.8934041355699218e+00 3.2357693155049283e+00 0 1 0 +338 1 3 -1.0500000000000000e+00 6.3569045021168691e-01 -1.2070565156037954e+01 3.2374462468578749e+00 0 1 0 +339 1 3 -1.0500000000000000e+00 -5.1770556733988826e-01 -9.7445696176577137e+00 3.0459634759630063e+00 0 1 0 +340 1 5 4.2499999999999999e-01 2.8948985199675210e+00 -1.2764300231969152e+01 1.1507672489080729e+00 0 1 0 +341 1 1 1.5750000000000000e+00 2.5034344422152106e+00 -1.0455505379844039e+01 -3.7523281344018500e-03 0 1 0 +342 1 2 2.1000000000000001e+00 1.7144048897053548e+00 -1.7829278827200582e+01 -2.7609375642366514e+00 0 1 0 +343 1 2 2.1000000000000001e+00 1.6910990452522778e+00 -1.1818431965120766e+01 -2.7688521544223557e+00 0 1 0 +344 1 3 -1.0500000000000000e+00 1.9119323284819547e+00 -8.9344496581989912e+00 -1.1428177382481586e+00 0 1 0 +345 1 3 -1.0500000000000000e+00 1.5563892707225317e+00 -1.1725703690663577e+01 -1.1439423397491009e+00 0 1 0 +346 1 4 -9.4999999999999996e-01 4.1971837724422230e+00 -1.0529223437421583e+01 -1.0140304498512833e+00 0 1 0 +347 1 3 -1.0500000000000000e+00 5.5462795339137028e+00 -1.2521387157719200e+01 -3.2425682558207303e+00 0 1 0 +348 1 3 -1.0500000000000000e+00 1.8034351269669298e+00 -1.0344148858506074e+01 -3.2446357157915351e+00 0 1 0 +349 1 3 -1.0500000000000000e+00 2.9565987372624374e+00 -1.2670221018382025e+01 -3.0529474743907752e+00 0 1 0 +350 1 5 4.2499999999999999e-01 4.7040264803948517e+00 -9.6504758402318025e+00 -1.1578593135248099e+00 0 1 0 +351 1 1 1.5750000000000000e+00 -1.0471558842234785e-01 -1.4938400364160536e+01 -3.7532330236462741e-03 0 1 0 +352 1 2 2.1000000000000001e+00 4.3225692029115947e+00 -1.3346363976966739e+01 -2.7609380283517364e+00 0 1 0 +353 1 2 2.1000000000000001e+00 4.2429709170616423e+00 -1.6301375789705347e+01 -2.7688688655989422e+00 0 1 0 +354 1 3 -1.0500000000000000e+00 4.4637558178452430e+00 -1.3417379075377282e+01 -1.1428141432543626e+00 0 1 0 +355 1 3 -1.0500000000000000e+00 4.1082428565530851e+00 -1.6208643768110964e+01 -1.1439575855412993e+00 0 1 0 +356 1 4 -9.4999999999999996e-01 1.5890483233411512e+00 -1.5012116338313390e+01 -1.0140187450303042e+00 0 1 0 +357 1 3 -1.0500000000000000e+00 2.9381893438004383e+00 -1.7004282362058166e+01 -3.2425562113891360e+00 0 1 0 +358 1 3 -1.0500000000000000e+00 4.3552644383759880e+00 -1.4827036483227031e+01 -3.2446472860660487e+00 0 1 0 +359 1 3 -1.0500000000000000e+00 5.5084200493482207e+00 -1.7153088410673128e+01 -3.0529633116519523e+00 0 1 0 +360 1 5 4.2499999999999999e-01 2.0958519709362449e+00 -1.4133378407095304e+01 -1.1577903583398630e+00 0 1 0 +361 1 1 1.5750000000000000e+00 7.6473300699624751e+00 -1.6442095286891750e+01 -3.2703635846598189e-03 0 1 0 +362 1 2 2.1000000000000001e+00 -1.2203692618505173e+01 -9.0683357616495428e+00 2.7539509521771546e+00 1 1 0 +363 1 2 2.1000000000000001e+00 -1.2180359496617088e+01 -1.5079150525191121e+01 2.7618176073756171e+00 1 1 0 +364 1 3 -1.0500000000000000e+00 8.2390082609686672e+00 -1.7962998453343072e+01 1.1357656996613876e+00 0 1 0 +365 1 3 -1.0500000000000000e+00 -1.2045675817277496e+01 -1.5172133958248716e+01 1.1369942170488319e+00 1 1 0 +366 1 4 -9.4999999999999996e-01 5.9536694527401863e+00 -1.6368316601029903e+01 1.0070080197153732e+00 0 1 0 +367 1 3 -1.0500000000000000e+00 4.6044999502781359e+00 -1.4376299637797334e+01 3.2357807367951334e+00 0 1 0 +368 1 3 -1.0500000000000000e+00 -1.2292484484628849e+01 -1.6553497884316052e+01 3.2374506520275279e+00 1 1 0 +369 1 3 -1.0500000000000000e+00 7.1941227993251466e+00 -1.4227441518171391e+01 3.0459466724115387e+00 0 1 0 +370 1 5 4.2499999999999999e-01 5.4467316809031381e+00 -1.7247181780075401e+01 1.1509108228447804e+00 0 1 0 +371 1 1 1.5750000000000000e+00 -1.0384509878063577e+01 -1.1959202847679125e+01 -3.2711064931607581e-03 1 1 0 +372 1 2 2.1000000000000001e+00 5.8281658705053552e+00 -1.3551245908771351e+01 2.7539592284405323e+00 0 1 0 +373 1 2 2.1000000000000001e+00 5.9077738247842859e+00 -1.0596222346036228e+01 2.7618212472175525e+00 0 1 0 +374 1 3 -1.0500000000000000e+00 5.6872004561341356e+00 -1.3480068502065599e+01 1.1357317122361454e+00 0 1 0 +375 1 3 -1.0500000000000000e+00 6.0424675752151202e+00 -1.0689198215110313e+01 1.1370119790707562e+00 0 1 0 +376 1 4 -9.4999999999999996e-01 -1.2078208028614750e+01 -1.1885444143137754e+01 1.0070061177644991e+00 1 1 0 +377 1 3 -1.0500000000000000e+00 7.2126361390250970e+00 -9.8933805239822377e+00 3.2357588745576784e+00 0 1 0 +378 1 3 -1.0500000000000000e+00 5.7956884111784390e+00 -1.2070595254996373e+01 3.2374511312518859e+00 0 1 0 +379 1 3 -1.0500000000000000e+00 4.6422879410256392e+00 -9.7445663758382555e+00 3.0459651484494685e+00 0 1 0 +380 1 5 4.2499999999999999e-01 8.0549327596562676e+00 -1.2764265216608282e+01 1.1508699292293620e+00 0 1 0 +381 1 1 1.5750000000000000e+00 7.6634431466777784e+00 -1.0455505708640878e+01 -3.7548033538037373e-03 0 1 0 +382 1 2 2.1000000000000001e+00 6.8744083301107217e+00 -1.7829293052197659e+01 -2.7609466521728914e+00 0 1 0 +383 1 2 2.1000000000000001e+00 6.8511227655710272e+00 -1.1818423654764077e+01 -2.7688514413745127e+00 0 1 0 +384 1 3 -1.0500000000000000e+00 7.0719252612919341e+00 -8.9344460915840020e+00 -1.1428009362290084e+00 0 1 0 +385 1 3 -1.0500000000000000e+00 6.7163919273608208e+00 -1.1725714227503657e+01 -1.1439356358725981e+00 0 1 0 +386 1 4 -9.4999999999999996e-01 -1.1282825542264309e+01 -1.0529236312045516e+01 -1.0140115555323934e+00 1 1 0 +387 1 3 -1.0500000000000000e+00 -9.9336734334620846e+00 -1.2521362616099530e+01 -3.2425798517804285e+00 1 1 0 +388 1 3 -1.0500000000000000e+00 6.9634372372059339e+00 -1.0344120541373844e+01 -3.2446411197658893e+00 0 1 0 +389 1 3 -1.0500000000000000e+00 8.1166063278059539e+00 -1.2670225192721546e+01 -3.0529487788076324e+00 0 1 0 +390 1 5 4.2499999999999999e-01 -1.0775939522237591e+01 -9.6504409144075929e+00 -1.1577656550448125e+00 1 1 0 +391 1 1 1.5750000000000000e+00 5.0552705213441183e+00 -1.4938390885101004e+01 -3.7556755525152141e-03 0 1 0 +392 1 2 2.1000000000000001e+00 -1.1157454505789488e+01 -1.3346365259602514e+01 -2.7609477580902304e+00 1 1 0 +393 1 2 2.1000000000000001e+00 -1.1237035180060985e+01 -1.6301363128204752e+01 -2.7688574109066444e+00 1 1 0 +394 1 3 -1.0500000000000000e+00 -1.1016258515593059e+01 -1.3417381597335801e+01 -1.1427868565141956e+00 1 1 0 +395 1 3 -1.0500000000000000e+00 -1.1371754569044754e+01 -1.6208638414131233e+01 -1.1439607996348045e+00 1 1 0 +396 1 4 -9.4999999999999996e-01 6.7490784560440211e+00 -1.5012076202167444e+01 -1.0140027578594140e+00 0 1 0 +397 1 3 -1.0500000000000000e+00 8.0981866850365734e+00 -1.7004283665969044e+01 -3.2425625386787402e+00 0 1 0 +398 1 3 -1.0500000000000000e+00 -1.1124739912558308e+01 -1.4827054551632816e+01 -3.2446301023047264e+00 1 1 0 +399 1 3 -1.0500000000000000e+00 -9.9715680099552539e+00 -1.7153093163802694e+01 -3.0529662797145232e+00 1 1 0 +400 1 5 4.2499999999999999e-01 7.2558685014983197e+00 -1.4133366923834902e+01 -1.1576429969303437e+00 0 1 0 +401 1 1 1.5750000000000000e+00 -7.8326838930931588e+00 -1.6442085371931373e+01 -3.2732823819223711e-03 1 1 0 +402 1 2 2.1000000000000001e+00 -7.0436687618137706e+00 -9.0683330137854199e+00 2.7539612939828899e+00 1 1 0 +403 1 2 2.1000000000000001e+00 -7.0203552020415820e+00 -1.5079163689271947e+01 2.7618054084239976e+00 1 1 0 +404 1 3 -1.0500000000000000e+00 -7.2409778107259708e+00 -1.7962996502787455e+01 1.1357372000778803e+00 1 1 0 +405 1 3 -1.0500000000000000e+00 -6.8856791733648324e+00 -1.5172137885807103e+01 1.1369963196178823e+00 1 1 0 +406 1 4 -9.4999999999999996e-01 -9.5262993670970957e+00 -1.6368274059361951e+01 1.0070224743079983e+00 1 1 0 +407 1 3 -1.0500000000000000e+00 -1.0875507123551024e+01 -1.4376303441124719e+01 3.2357750518877921e+00 1 1 0 +408 1 3 -1.0500000000000000e+00 -7.1324812203291952e+00 -1.6553483309654993e+01 3.2374341141377876e+00 1 1 0 +409 1 3 -1.0500000000000000e+00 -8.2858895255051763e+00 -1.4227436498303321e+01 3.0459500397149455e+00 1 1 0 +410 1 5 4.2499999999999999e-01 -1.0033255030691558e+01 -1.7247173624416206e+01 1.1510522172719124e+00 1 1 0 +411 1 1 1.5750000000000000e+00 -5.2245178771227252e+00 -1.1959202758526017e+01 -3.2686596132034396e-03 1 1 0 +412 1 2 2.1000000000000001e+00 -9.6518281984812564e+00 -1.3551260332238776e+01 2.7539503258911147e+00 1 1 0 +413 1 2 2.1000000000000001e+00 -9.5722019707608350e+00 -1.0596214958141957e+01 2.7618209577011115e+00 1 1 0 +414 1 3 -1.0500000000000000e+00 -9.7928062006518743e+00 -1.3480064638111777e+01 1.1357461718012836e+00 1 1 0 +415 1 3 -1.0500000000000000e+00 -9.4375295209633592e+00 -1.0689208902166378e+01 1.1370191291599561e+00 1 1 0 +416 1 4 -9.4999999999999996e-01 -6.9182015257625187e+00 -1.1885434141823438e+01 1.0069865076337194e+00 1 1 0 +417 1 3 -1.0500000000000000e+00 -8.2674096516605591e+00 -9.8934036664961500e+00 3.2357692780579193e+00 1 1 0 +418 1 3 -1.0500000000000000e+00 -9.6843094688930229e+00 -1.2070565339252298e+01 3.2374457243298291e+00 1 1 0 +419 1 3 -1.0500000000000000e+00 -1.0837706493502655e+01 -9.7445692971577635e+00 3.0459634859134095e+00 1 1 0 +420 1 5 4.2499999999999999e-01 -7.4251012846331328e+00 -1.2764299901878989e+01 1.1507685978831965e+00 1 1 0 +421 1 1 1.5750000000000000e+00 -7.8165653710802498e+00 -1.0455505239212570e+01 -3.7526247607146956e-03 1 1 0 +422 1 2 2.1000000000000001e+00 -8.6055950659194451e+00 -1.7829279483493142e+01 -2.7609372605772293e+00 1 1 0 +423 1 2 2.1000000000000001e+00 -8.6289008782796017e+00 -1.1818431879204407e+01 -2.7688521292950892e+00 1 1 0 +424 1 3 -1.0500000000000000e+00 -8.4080675550031589e+00 -8.9344488405749729e+00 -1.1428176752375947e+00 1 1 0 +425 1 3 -1.0500000000000000e+00 -8.7636107163403185e+00 -1.1725704386940036e+01 -1.1439420773679156e+00 1 1 0 +426 1 4 -9.4999999999999996e-01 -6.1228163916760510e+00 -1.0529224175237184e+01 -1.0140309851989482e+00 1 1 0 +427 1 3 -1.0500000000000000e+00 -4.7737195815235491e+00 -1.2521386711486187e+01 -3.2425678127633280e+00 1 1 0 +428 1 3 -1.0500000000000000e+00 -8.5165649126724521e+00 -1.0344149018842892e+01 -3.2446367291315585e+00 1 1 0 +429 1 3 -1.0500000000000000e+00 -7.3634018650483775e+00 -1.2670221015317008e+01 -3.0529473079508476e+00 1 1 0 +430 1 5 4.2499999999999999e-01 -5.6159739075346202e+00 -9.6504763623609211e+00 -1.1578626433938446e+00 1 1 0 +431 1 1 1.5750000000000000e+00 -1.0424715562756791e+01 -1.4938400553082197e+01 -3.7529812015879571e-03 1 1 0 +432 1 2 2.1000000000000001e+00 -5.9974311083098977e+00 -1.3346363613537441e+01 -2.7609379380798256e+00 1 1 0 +433 1 2 2.1000000000000001e+00 -6.0770293492200240e+00 -1.6301376203040785e+01 -2.7688686473689419e+00 1 1 0 +434 1 3 -1.0500000000000000e+00 -5.8562441201571032e+00 -1.3417379284137553e+01 -1.1428148565171732e+00 1 1 0 +435 1 3 -1.0500000000000000e+00 -6.2117573594784972e+00 -1.6208643250903787e+01 -1.1439581431602814e+00 1 1 0 +436 1 4 -9.4999999999999996e-01 -8.7309519339587123e+00 -1.5012116780663984e+01 -1.0140186145754715e+00 1 1 0 +437 1 3 -1.0500000000000000e+00 -7.3818111353884994e+00 -1.7004282131950792e+01 -3.2425561129342411e+00 1 1 0 +438 1 3 -1.0500000000000000e+00 -5.9647356400559168e+00 -1.4827036902064780e+01 -3.2446470576896891e+00 1 1 0 +439 1 3 -1.0500000000000000e+00 -4.8115794831903598e+00 -1.7153088674562756e+01 -3.0529634737335600e+00 1 1 0 +440 1 5 4.2499999999999999e-01 -8.2241476630143868e+00 -1.4133377854348987e+01 -1.1577899116091555e+00 1 1 0 +441 1 1 1.5750000000000000e+00 -2.6726699900750228e+00 -1.6442095184071334e+01 -3.2708152303708715e-03 1 1 0 +442 1 2 2.1000000000000001e+00 -1.8836926728028871e+00 -9.0683360706481988e+00 2.7539509370400470e+00 1 1 0 +443 1 2 2.1000000000000001e+00 -1.8603595713516334e+00 -1.5079150161517486e+01 2.7618175803065235e+00 1 1 0 +444 1 3 -1.0500000000000000e+00 -2.0809915940246260e+00 -1.7962997831100317e+01 1.1357659249768037e+00 1 1 0 +445 1 3 -1.0500000000000000e+00 -1.7256757375340950e+00 -1.5172134571584408e+01 1.1369946994743039e+00 1 1 0 +446 1 4 -9.4999999999999996e-01 -4.3663303959113087e+00 -1.6368316840061311e+01 1.0070078045087598e+00 1 1 0 +447 1 3 -1.0500000000000000e+00 -5.7154995299878735e+00 -1.4376299278351169e+01 3.2357812249751525e+00 1 1 0 +448 1 3 -1.0500000000000000e+00 -1.9724845002142448e+00 -1.6553498331239307e+01 3.2374496312659460e+00 1 1 0 +449 1 3 -1.0500000000000000e+00 -3.1258773791373198e+00 -1.4227441660105004e+01 3.0459467420251194e+00 1 1 0 +450 1 5 4.2499999999999999e-01 -4.8732684553684695e+00 -1.7247182150638707e+01 1.1509092295157224e+00 1 1 0 +451 1 1 1.5750000000000000e+00 -6.4509876999837346e-02 -1.1959203109449142e+01 -3.2708769273028793e-03 1 1 0 +452 1 2 2.1000000000000001e+00 -4.4918347776990135e+00 -1.3551245280844766e+01 2.7539590818090893e+00 1 1 0 +453 1 2 2.1000000000000001e+00 -4.4122264005535730e+00 -1.0596223265618471e+01 2.7618213123579540e+00 1 1 0 +454 1 3 -1.0500000000000000e+00 -4.6327993770775722e+00 -1.3480068776200241e+01 1.1357306843562007e+00 1 1 0 +455 1 3 -1.0500000000000000e+00 -4.2775323301208692e+00 -1.0689197415521184e+01 1.1370113492700824e+00 1 1 0 +456 1 4 -9.4999999999999996e-01 -1.7582085114615111e+00 -1.1885444828152252e+01 1.0070062173292218e+00 1 1 0 +457 1 3 -1.0500000000000000e+00 -3.1073643655971166e+00 -9.8933800969646732e+00 3.2357583287275880e+00 1 1 0 +458 1 3 -1.0500000000000000e+00 -4.5243114909096018e+00 -1.2070595204559629e+01 3.2374516197245775e+00 1 1 0 +459 1 3 -1.0500000000000000e+00 -5.6777118011680381e+00 -9.7445664568842254e+00 3.0459653648294243e+00 1 1 0 +460 1 5 4.2499999999999999e-01 -2.2650668296403058e+00 -1.2764264287005354e+01 1.1508705187769799e+00 1 1 0 +461 1 1 1.5750000000000000e+00 -2.6565565918664173e+00 -1.0455505879441525e+01 -3.7549348428154161e-03 1 1 0 +462 1 2 2.1000000000000001e+00 -3.4455908391566643e+00 -1.7829293092612534e+01 -2.7609464806422892e+00 1 1 0 +463 1 2 2.1000000000000001e+00 -3.4688767904129696e+00 -1.1818423511849518e+01 -2.7688516686671711e+00 1 1 0 +464 1 3 -1.0500000000000000e+00 -3.2480752505918087e+00 -8.9344459968549881e+00 -1.1428004913510801e+00 1 1 0 +465 1 3 -1.0500000000000000e+00 -3.6036086619536984e+00 -1.1725714425851610e+01 -1.1439355502562485e+00 1 1 0 +466 1 4 -9.4999999999999996e-01 -9.6282526002298496e-01 -1.0529236900614441e+01 -1.0140115755842860e+00 1 1 0 +467 1 3 -1.0500000000000000e+00 3.8632613444500308e-01 -1.2521362577138564e+01 -3.2425797939291590e+00 1 1 0 +468 1 3 -1.0500000000000000e+00 -3.3565633803144257e+00 -1.0344120627751945e+01 -3.2446417136325554e+00 1 1 0 +469 1 3 -1.0500000000000000e+00 -2.2033940096388758e+00 -1.2670225163556584e+01 -3.0529490801396841e+00 1 1 0 +470 1 5 4.2499999999999999e-01 -4.5593933850753388e-01 -9.6504406470385522e+00 -1.1577660591579200e+00 1 1 0 +471 1 1 1.5750000000000000e+00 -5.2647294099161668e+00 -1.4938390849710533e+01 -3.7554421477974387e-03 1 1 0 +472 1 2 2.1000000000000001e+00 -8.3745420972569029e-01 -1.3346365774570319e+01 -2.7609475596234478e+00 1 1 0 +473 1 2 2.1000000000000001e+00 -9.1703537310051608e-01 -1.6301362578024104e+01 -2.7688573923577673e+00 1 1 0 +474 1 3 -1.0500000000000000e+00 -6.9625852330998939e-01 -1.3417381412652670e+01 -1.1427865734610130e+00 1 1 0 +475 1 3 -1.0500000000000000e+00 -1.0517542431933027e+00 -1.6208638871829955e+01 -1.1439604905627423e+00 1 1 0 +476 1 4 -9.4999999999999996e-01 -3.5709214848472897e+00 -1.5012075671946061e+01 -1.0140027621155667e+00 1 1 0 +477 1 3 -1.0500000000000000e+00 -2.2218134642601797e+00 -1.7004283740992047e+01 -3.2425628740632551e+00 1 1 0 +478 1 3 -1.0500000000000000e+00 -8.0473984685049871e-01 -1.4827054452774018e+01 -3.2446303282137938e+00 1 1 0 +479 1 3 -1.0500000000000000e+00 3.4843154859986214e-01 -1.7153093111175764e+01 -3.0529662393152108e+00 1 1 0 +480 1 5 4.2499999999999999e-01 -3.0641314229533227e+00 -1.4133366897183697e+01 -1.1576420001890888e+00 1 1 0 +481 1 1 1.5750000000000000e+00 2.5436575698973183e+00 -7.4762807567511658e+00 -3.2681608649411942e-03 0 1 0 +482 1 2 2.1000000000000001e+00 3.3326771644182021e+00 -1.0251055584260627e-01 2.7539562495680912e+00 0 1 0 +483 1 2 2.1000000000000001e+00 3.3559732863378500e+00 -6.1133477231204605e+00 2.7618019815700912e+00 0 1 0 +484 1 3 -1.0500000000000000e+00 3.1353688973965141e+00 -8.9971784534458905e+00 1.1357161192366334e+00 0 1 0 +485 1 3 -1.0500000000000000e+00 3.4906521933711527e+00 -6.2063093440944606e+00 1.1370013682474660e+00 0 1 0 +486 1 4 -9.4999999999999996e-01 8.4999416594662414e-01 -7.4025141664959477e+00 1.0069772303784212e+00 0 1 0 +487 1 3 -1.0500000000000000e+00 -4.9918531211513084e-01 -5.4104789806646600e+00 3.2357748645072224e+00 0 1 0 +488 1 3 -1.0500000000000000e+00 3.2438478921430658e+00 -7.5876613926832288e+00 3.2374650513379368e+00 0 1 0 +489 1 3 -1.0500000000000000e+00 2.0904479338721824e+00 -5.2616143373361730e+00 3.0459494998857473e+00 0 1 0 +490 1 5 4.2499999999999999e-01 3.4305735839570417e-01 -8.2814451510232985e+00 1.1506997919603279e+00 0 1 0 +491 1 1 1.5750000000000000e+00 5.1518162806579664e+00 -2.9933577707057264e+00 -3.2719737650719338e-03 0 1 0 +492 1 2 2.1000000000000001e+00 7.2450056662052376e-01 -4.5854449159198332e+00 2.7539595529080376e+00 0 1 0 +493 1 2 2.1000000000000001e+00 8.0414918868178020e-01 -1.6304050196450568e+00 2.7618170330682865e+00 0 1 0 +494 1 3 -1.0500000000000000e+00 5.8351556926552206e-01 -4.5142509399890525e+00 1.1357618537192042e+00 0 1 0 +495 1 3 -1.0500000000000000e+00 9.3881877218889187e-01 -1.7234004054205592e+00 1.1370055641638572e+00 0 1 0 +496 1 4 -9.4999999999999996e-01 3.4581831713214264e+00 -2.9195538038595128e+00 1.0070161949531542e+00 0 1 0 +497 1 3 -1.0500000000000000e+00 2.1089597637650321e+00 -9.2758109333887262e-01 3.2357778931579837e+00 0 1 0 +498 1 3 -1.0500000000000000e+00 6.9202493621660821e-01 -3.1047407556425863e+00 3.2374286426884460e+00 0 1 0 +499 1 3 -1.0500000000000000e+00 -4.6137640541853386e-01 -7.7872267536189810e-01 3.0459549651529940e+00 0 1 0 +500 1 5 4.2499999999999999e-01 2.9512366629883733e+00 -3.7984283160022585e+00 1.1510066071998590e+00 0 1 0 +501 1 1 1.5750000000000000e+00 2.5597764890479056e+00 -1.4896728825261896e+00 -3.7510557474558226e-03 0 1 0 +502 1 2 2.1000000000000001e+00 1.7707367658906890e+00 -8.8634435099187865e+00 -2.7609471549488367e+00 0 1 0 +503 1 2 2.1000000000000001e+00 1.7474499480691374e+00 -2.8526347731487149e+00 -2.7688625207492397e+00 0 1 0 +504 1 3 -1.0500000000000000e+00 1.9682617548841872e+00 3.1354766712723858e-02 -1.1428194347213658e+00 0 1 0 +505 1 3 -1.0500000000000000e+00 1.6127391948302812e+00 -2.7598942364919772e+00 -1.1439556954086907e+00 0 1 0 +506 1 4 -9.4999999999999996e-01 4.2535424365009327e+00 -1.5633894774555195e+00 -1.0140400418681299e+00 0 1 0 +507 1 3 -1.0500000000000000e+00 5.6026491085120664e+00 -3.5555609449644461e+00 -3.2425576785307024e+00 0 1 0 +508 1 3 -1.0500000000000000e+00 1.8597625543053109e+00 -1.3783257788357659e+00 -3.2446235882093193e+00 0 1 0 +509 1 3 -1.0500000000000000e+00 3.0129281343278276e+00 -3.7043645719831666e+00 -3.0529605899078920e+00 0 1 0 +510 1 5 4.2499999999999999e-01 4.7603403166335863e+00 -6.8469223618015818e-01 -1.1579216441180478e+00 0 1 0 +511 1 1 1.5750000000000000e+00 -4.8390666169016328e-02 -5.9725694760793182e+00 -3.7574054098818976e-03 0 1 0 +512 1 2 2.1000000000000001e+00 4.3789145761620833e+00 -4.3805514632713773e+00 -2.7609339008297651e+00 0 1 0 +513 1 2 2.1000000000000001e+00 4.2992990506123103e+00 -7.3355316180595338e+00 -2.7688607932569447e+00 0 1 0 +514 1 3 -1.0500000000000000e+00 4.5200860118647945e+00 -4.4515414547653052e+00 -1.1427984036885626e+00 0 1 0 +515 1 3 -1.0500000000000000e+00 4.1645706838576562e+00 -7.2428167611125112e+00 -1.1439527343219709e+00 0 1 0 +516 1 4 -9.4999999999999996e-01 1.6453970630033830e+00 -6.0462561133443451e+00 -1.0139809143366438e+00 0 1 0 +517 1 3 -1.0500000000000000e+00 2.9945122334512657e+00 -8.0384625674130401e+00 -3.2425618392344440e+00 0 1 0 +518 1 3 -1.0500000000000000e+00 4.4116077983548383e+00 -5.8612132939321402e+00 -3.2446764319665711e+00 0 1 0 +519 1 3 -1.0500000000000000e+00 5.5647564535540042e+00 -8.1872858674545341e+00 -3.0529539697099937e+00 0 1 0 +520 1 5 4.2499999999999999e-01 2.1522145539965809e+00 -5.1674642083276847e+00 -1.1575048043055780e+00 0 1 0 +521 1 1 1.5750000000000000e+00 7.7036718214034785e+00 -7.4762910233615827e+00 -3.2653078128408453e-03 0 1 0 +522 1 2 2.1000000000000001e+00 -1.2147345593282450e+01 -1.0251359496978196e-01 2.7539461566052985e+00 1 1 0 +523 1 2 2.1000000000000001e+00 -1.2124030375241905e+01 -6.1133337616709902e+00 2.7618143580363075e+00 1 1 0 +524 1 3 -1.0500000000000000e+00 8.2953539893182153e+00 -8.9971801103008087e+00 1.1357452560675760e+00 0 1 0 +525 1 3 -1.0500000000000000e+00 -1.1989344710863094e+01 -6.2063052996612100e+00 1.1369992978851666e+00 1 1 0 +526 1 4 -9.4999999999999996e-01 6.0099622042933412e+00 -7.4025579776391464e+00 1.0069620216105442e+00 0 1 0 +527 1 3 -1.0500000000000000e+00 4.6608198109043748e+00 -5.4104755502326540e+00 3.2357801936372788e+00 0 1 0 +528 1 3 -1.0500000000000000e+00 -1.2236155841755377e+01 -7.5876771945797863e+00 3.2374811955831060e+00 1 1 0 +529 1 3 -1.0500000000000000e+00 7.2504604436044637e+00 -5.2616189118410208e+00 3.0459453948467168e+00 0 1 0 +530 1 5 4.2499999999999999e-01 5.5030432428799969e+00 -8.2814548631033578e+00 1.1505519475195651e+00 0 1 0 +531 1 1 1.5750000000000000e+00 -1.0328175895563996e+01 -2.9933575426158416e+00 -3.2744817930581149e-03 1 1 0 +532 1 2 2.1000000000000001e+00 5.8844947594629744e+00 -4.5854310172663979e+00 2.7539684166484335e+00 0 1 0 +533 1 2 2.1000000000000001e+00 5.9641241815446477e+00 -1.6304119441692926e+00 2.7618170105232309e+00 0 1 0 +534 1 3 -1.0500000000000000e+00 5.7435221593356864e+00 -4.5142545324410897e+00 1.1357475728004847e+00 0 1 0 +535 1 3 -1.0500000000000000e+00 6.0988162421821528e+00 -1.7233902325835047e+00 1.1369987706733902e+00 0 1 0 +536 1 4 -9.4999999999999996e-01 -1.2021823199294937e+01 -2.9195626861295096e+00 1.0070363114076599e+00 1 1 0 +537 1 3 -1.0500000000000000e+00 7.2690066204394697e+00 -9.2755674730927851e-01 3.2357668612914487e+00 0 1 0 +538 1 3 -1.0500000000000000e+00 5.8520231027928773e+00 -3.1047706349297179e+00 3.2374344835306346e+00 0 1 0 +539 1 3 -1.0500000000000000e+00 4.6986174638786373e+00 -7.7871980724010115e-01 3.0459566060165137e+00 0 1 0 +540 1 5 4.2499999999999999e-01 8.1112714877724414e+00 -3.7983924620060368e+00 1.1511131184559726e+00 0 1 0 +541 1 1 1.5750000000000000e+00 7.7197852579331645e+00 -1.4896736083571689e+00 -3.7533060240022564e-03 0 1 0 +542 1 2 2.1000000000000001e+00 6.9307402907651401e+00 -8.8634573665418070e+00 -2.7609563100003145e+00 0 1 0 +543 1 2 2.1000000000000001e+00 6.9074738694113726e+00 -2.8526269036832552e+00 -2.7688615983007780e+00 0 1 0 +544 1 3 -1.0500000000000000e+00 7.1282543967930359e+00 3.1358883413265204e-02 -1.1428023230370439e+00 0 1 0 +545 1 3 -1.0500000000000000e+00 6.7727419364633441e+00 -2.7599051276576141e+00 -1.1439490121146996e+00 0 1 0 +546 1 4 -9.4999999999999996e-01 -1.1226466741815884e+01 -1.5634024412045342e+00 -1.0140216083145610e+00 1 1 0 +547 1 3 -1.0500000000000000e+00 -9.8773043947366048e+00 -3.5555368621683208e+00 -3.2425683285331646e+00 1 1 0 +548 1 3 -1.0500000000000000e+00 7.0197645195179135e+00 -1.3782969003001959e+00 -3.2446289771148944e+00 0 1 0 +549 1 3 -1.0500000000000000e+00 8.1729347482067567e+00 -3.7043681527678913e+00 -3.0529625378704122e+00 0 1 0 +550 1 5 4.2499999999999999e-01 -1.0719626421899999e+01 -6.8465756426241953e-01 -1.1578295867776784e+00 1 1 0 +551 1 1 1.5750000000000000e+00 5.1115953590272625e+00 -5.9725597637293362e+00 -3.7601916249858647e-03 0 1 0 +552 1 2 2.1000000000000001e+00 -1.1101108931968247e+01 -4.3805528895496302e+00 -2.7609432872668886e+00 1 1 0 +553 1 2 2.1000000000000001e+00 -1.1180707067380455e+01 -7.3355188643798535e+00 -2.7688492591590554e+00 1 1 0 +554 1 3 -1.0500000000000000e+00 -1.0959928694497696e+01 -4.4515436898974556e+00 -1.1427711527976001e+00 1 1 0 +555 1 3 -1.0500000000000000e+00 -1.1315426415312240e+01 -7.2428113900070752e+00 -1.1439555106248189e+00 1 1 0 +556 1 4 -9.4999999999999996e-01 6.8054277571583519e+00 -6.0462150488380164e+00 -1.0139639895733374e+00 0 1 0 +557 1 3 -1.0500000000000000e+00 8.1545095181602107e+00 -8.0384640840914869e+00 -3.2425680420518717e+00 0 1 0 +558 1 3 -1.0500000000000000e+00 -1.1068396240802272e+01 -5.8612309436472234e+00 -3.2446597028975566e+00 1 1 0 +559 1 3 -1.0500000000000000e+00 -9.9152309072003355e+00 -8.1872904891822973e+00 -3.0529571692262092e+00 1 1 0 +560 1 5 4.2499999999999999e-01 7.3122321320503794e+00 -5.1674508614420542e+00 -1.1573511315660259e+00 0 1 0 +561 1 1 1.5750000000000000e+00 -7.7763421850555563e+00 -7.4762809230994502e+00 -3.2682934864940449e-03 1 1 0 +562 1 2 2.1000000000000001e+00 -6.9873219863206382e+00 -1.0251132671459473e-01 2.7539563597780923e+00 1 1 0 +563 1 2 2.1000000000000001e+00 -6.9640259840326628e+00 -6.1133472592188820e+00 2.7618022956295629e+00 1 1 0 +564 1 3 -1.0500000000000000e+00 -7.1846314193998664e+00 -8.9971779600544295e+00 1.1357163882947159e+00 1 1 0 +565 1 3 -1.0500000000000000e+00 -6.8293485880591112e+00 -6.2063096894111425e+00 1.1370012333877977e+00 1 1 0 +566 1 4 -9.4999999999999996e-01 -9.4700055755924701e+00 -7.4025139876644594e+00 1.0069773362883989e+00 1 1 0 +567 1 3 -1.0500000000000000e+00 -1.0819186074870123e+01 -5.4104790908412692e+00 3.2357742683187052e+00 1 1 0 +568 1 3 -1.0500000000000000e+00 -7.0761528036457531e+00 -7.5876609775127299e+00 3.2374644576831670e+00 1 1 0 +569 1 3 -1.0500000000000000e+00 -8.2295514763541018e+00 -5.2616148976108672e+00 3.0459489432022515e+00 1 1 0 +570 1 5 4.2499999999999999e-01 -9.9769424641830984e+00 -8.2814450142459481e+00 1.1507004566801982e+00 1 1 0 +571 1 1 1.5750000000000000e+00 -5.1681838127975688e+00 -2.9933576384022018e+00 -3.2717369706762867e-03 1 1 0 +572 1 2 2.1000000000000001e+00 -9.5954996993209818e+00 -4.5854449940775464e+00 2.7539595842160942e+00 1 1 0 +573 1 2 2.1000000000000001e+00 -9.5158507875170635e+00 -1.6304043820163336e+00 2.7618168255845852e+00 1 1 0 +574 1 3 -1.0500000000000000e+00 -9.7364845194737679e+00 -4.5142510709812989e+00 1.1357620952221374e+00 1 1 0 +575 1 3 -1.0500000000000000e+00 -9.3811811495596569e+00 -1.7234005945692772e+00 1.1370052607441838e+00 1 1 0 +576 1 4 -9.4999999999999996e-01 -6.8618165785256515e+00 -2.9195528214605435e+00 1.0070162671680265e+00 1 1 0 +577 1 3 -1.0500000000000000e+00 -8.2110400227350908e+00 -9.2758055861539646e-01 3.2357776111175447e+00 1 1 0 +578 1 3 -1.0500000000000000e+00 -9.6279751712075452e+00 -3.1047410652821092e+00 3.2374288782542173e+00 1 1 0 +579 1 3 -1.0500000000000000e+00 -1.0781377378976435e+01 -7.7872238917679937e-01 3.0459548222147177e+00 1 1 0 +580 1 5 4.2499999999999999e-01 -7.3687631344134621e+00 -3.7984280683325675e+00 1.1510087811947294e+00 1 1 0 +581 1 1 1.5750000000000000e+00 -7.7602231493103115e+00 -1.4896729773895174e+00 -3.7514049036762032e-03 1 1 0 +582 1 2 2.1000000000000001e+00 -8.5492636448235881e+00 -8.8634434759155383e+00 -2.7609469383151142e+00 1 1 0 +583 1 2 2.1000000000000001e+00 -8.5725493910960839e+00 -2.8526345568910330e+00 -2.7688621512718061e+00 1 1 0 +584 1 3 -1.0500000000000000e+00 -8.3517386022975746e+00 3.1355306993937404e-02 -1.1428188664021803e+00 1 1 0 +585 1 3 -1.0500000000000000e+00 -8.7072613660041132e+00 -2.7598948801617009e+00 -1.1439559119420721e+00 1 1 0 +586 1 4 -9.4999999999999996e-01 -6.0664578280469037e+00 -1.5633906786741285e+00 -1.0140407761717736e+00 1 1 0 +587 1 3 -1.0500000000000000e+00 -4.7173504441606600e+00 -3.5555605571846858e+00 -3.2425569990613576e+00 1 1 0 +588 1 3 -1.0500000000000000e+00 -8.4602377735195269e+00 -1.3783256930774925e+00 -3.2446245341017974e+00 1 1 0 +589 1 3 -1.0500000000000000e+00 -7.3070727313816795e+00 -3.7043646163271404e+00 -3.0529607277228852e+00 1 1 0 +590 1 5 4.2499999999999999e-01 -5.5596602828094399e+00 -6.8469307887884057e-01 -1.1579270767641230e+00 1 1 0 +591 1 1 1.5750000000000000e+00 -1.0368390725810965e+01 -5.9725695262430403e+00 -3.7573993430903840e-03 1 1 0 +592 1 2 2.1000000000000001e+00 -5.9410852260952272e+00 -4.3805507393552645e+00 -2.7609332752915812e+00 1 1 0 +593 1 2 2.1000000000000001e+00 -6.0207013841734955e+00 -7.3355318748997771e+00 -2.7688608337867908e+00 1 1 0 +594 1 3 -1.0500000000000000e+00 -5.7999138374145174e+00 -4.4515417632928145e+00 -1.1427994454172925e+00 1 1 0 +595 1 3 -1.0500000000000000e+00 -6.1554296040035208e+00 -7.2428163652707518e+00 -1.1439534513399927e+00 1 1 0 +596 1 4 -9.4999999999999996e-01 -8.6746031854828516e+00 -6.0462567207300957e+00 -1.0139806757747039e+00 1 1 0 +597 1 3 -1.0500000000000000e+00 -7.3254880189215017e+00 -8.0384622206913434e+00 -3.2425615735922868e+00 1 1 0 +598 1 3 -1.0500000000000000e+00 -5.9083924192090498e+00 -5.8612138215664249e+00 -3.2446762232977573e+00 1 1 0 +599 1 3 -1.0500000000000000e+00 -4.7552429311707556e+00 -8.1872863652617180e+00 -3.0529541602386461e+00 1 1 0 +600 1 5 4.2499999999999999e-01 -8.1677849706477055e+00 -5.1674634384285980e+00 -1.1575040236693965e+00 1 1 0 +601 1 1 1.5750000000000000e+00 -2.6163277838675221e+00 -7.4762909455420772e+00 -3.2656709391893912e-03 1 1 0 +602 1 2 2.1000000000000001e+00 -1.8273462383235461e+00 -1.0251424082924032e-01 2.7539460950975592e+00 1 1 0 +603 1 2 2.1000000000000001e+00 -1.8040299652667589e+00 -6.1133335430346563e+00 2.7618141317410618e+00 1 1 0 +604 1 3 -1.0500000000000000e+00 -2.0246462781465269e+00 -8.9971797593687484e+00 1.1357458882768405e+00 1 1 0 +605 1 3 -1.0500000000000000e+00 -1.6693450475600429e+00 -6.2063057861451725e+00 1.1369993464425061e+00 1 1 0 +606 1 4 -9.4999999999999996e-01 -4.3100379988542743e+00 -7.4025589029402692e+00 1.0069615315099991e+00 1 1 0 +607 1 3 -1.0500000000000000e+00 -5.6591796712508087e+00 -5.4104753627400228e+00 3.2357806674433647e+00 1 1 0 +608 1 3 -1.0500000000000000e+00 -1.9161562222272543e+00 -7.5876772803970987e+00 3.2374804258171608e+00 1 1 0 +609 1 3 -1.0500000000000000e+00 -3.0695406692448417e+00 -5.2616188661581340e+00 3.0459453864236909e+00 1 1 0 +610 1 5 4.2499999999999999e-01 -4.8169571538695717e+00 -8.2814553617741105e+00 1.1505481493262373e+00 1 1 0 +611 1 1 1.5750000000000000e+00 -8.1760772968380024e-03 -2.9933575181058600e+00 -3.2743711147666943e-03 1 1 0 +612 1 2 2.1000000000000001e+00 -4.4355051118200439e+00 -4.5854299392358087e+00 2.7539688922472791e+00 1 1 0 +613 1 2 2.1000000000000001e+00 -4.3558760344290208e+00 -1.6304124598534635e+00 2.7618174106720375e+00 1 1 0 +614 1 3 -1.0500000000000000e+00 -4.5764777419565466e+00 -4.5142548759855465e+00 1.1357463260141714e+00 1 1 0 +615 1 3 -1.0500000000000000e+00 -4.2211840342906868e+00 -1.7233895441759479e+00 1.1369977086180825e+00 1 1 0 +616 1 4 -9.4999999999999996e-01 -1.7018236124385560e+00 -2.9195635165858569e+00 1.0070367229964496e+00 1 1 0 +617 1 3 -1.0500000000000000e+00 -3.0509931277018758e+00 -9.2755589773917535e-01 3.2357665495488988e+00 1 1 0 +618 1 3 -1.0500000000000000e+00 -4.4679770346247647e+00 -3.1047713732493420e+00 3.2374347240366337e+00 1 1 0 +619 1 3 -1.0500000000000000e+00 -5.6213822534512161e+00 -7.7872002325319301e-01 3.0459565887809354e+00 1 1 0 +620 1 5 4.2499999999999999e-01 -2.2087277522865865e+00 -3.7983910799744223e+00 1.1511149260038867e+00 1 1 0 +621 1 1 1.5750000000000000e+00 -2.6002141654952915e+00 -1.4896737094533599e+00 -3.7533128050117881e-03 1 1 0 +622 1 2 2.1000000000000001e+00 -3.3892590053672063e+00 -8.8634574857208097e+00 -2.7609561680299493e+00 1 1 0 +623 1 2 2.1000000000000001e+00 -3.4125251930059894e+00 -2.8526268846259306e+00 -2.7688615286285891e+00 1 1 0 +624 1 3 -1.0500000000000000e+00 -3.1917462126351293e+00 3.1358788246325986e-02 -1.1428022026067133e+00 1 1 0 +625 1 3 -1.0500000000000000e+00 -3.5472590403252218e+00 -2.7599052235913142e+00 -1.1439491794483505e+00 1 1 0 +626 1 4 -9.4999999999999996e-01 -9.0646691514089461e-01 -1.5634032584722597e+00 -1.0140215315146257e+00 1 1 0 +627 1 3 -1.0500000000000000e+00 4.4269580016512577e-01 -3.5555364857703218e+00 -3.2425687501749536e+00 1 1 0 +628 1 3 -1.0500000000000000e+00 -3.3002363165323549e+00 -1.3782961327508190e+00 -3.2446289526978092e+00 1 1 0 +629 1 3 -1.0500000000000000e+00 -2.1470649566305173e+00 -3.7043686941940379e+00 -3.0529629239873710e+00 1 1 0 +630 1 5 4.2499999999999999e-01 -3.9962609031332441e-01 -6.8465733157457720e-01 -1.1578307953461699e+00 1 1 0 +631 1 1 1.5750000000000000e+00 -5.2084047404047134e+00 -5.9725595364899284e+00 -3.7600979616296826e-03 1 1 0 +632 1 2 2.1000000000000001e+00 -7.8110919308991456e-01 -4.3805529373242500e+00 -2.7609430555638124e+00 1 1 0 +633 1 2 2.1000000000000001e+00 -8.6070716056939567e-01 -7.3355179831783488e+00 -2.7688491805898519e+00 1 1 0 +634 1 3 -1.0500000000000000e+00 -6.3992886880595101e-01 -4.4515437816825045e+00 -1.1427704613142957e+00 1 1 0 +635 1 3 -1.0500000000000000e+00 -9.9542614064111312e-01 -7.2428116519511683e+00 -1.1439560424635076e+00 1 1 0 +636 1 4 -9.4999999999999996e-01 -3.5145719480547983e+00 -6.0462140630651522e+00 -1.0139637930845495e+00 1 1 0 +637 1 3 -1.0500000000000000e+00 -2.1654899354619133e+00 -8.0384635502983741e+00 -3.2425685873817418e+00 1 1 0 +638 1 3 -1.0500000000000000e+00 -7.4839646312622143e-01 -5.8612317329932946e+00 -3.2446596299773693e+00 1 1 0 +639 1 3 -1.0500000000000000e+00 4.0476806768967499e-01 -8.1872903970557633e+00 -3.0529571025848705e+00 1 1 0 +640 1 5 4.2499999999999999e-01 -3.0077675350384983e+00 -5.1674504112187361e+00 -1.1573483949331340e+00 1 1 0 +641 1 1 1.5750000000000000e+00 9.0327999603982079e-01 1.3078268179656156e+00 9.1936285392393344e+00 0 0 0 +642 1 2 2.1000000000000001e+00 5.0862246908167243e+00 9.0452767941395287e+00 -6.4424047165866876e+00 0 0 1 +643 1 2 2.1000000000000001e+00 5.1094714654176485e+00 3.0344442077888871e+00 -6.4345036943507274e+00 0 0 1 +644 1 3 -1.0500000000000000e+00 4.8887010421652999e+00 1.5046638157599901e-01 -8.0605839637767165e+00 0 0 1 +645 1 3 -1.0500000000000000e+00 5.2441927721705479e+00 2.9417321911529406e+00 -8.0593973812488873e+00 0 0 1 +646 1 4 -9.4999999999999996e-01 2.6033704126610484e+00 1.7451758067380290e+00 -8.1893676020018926e+00 0 0 1 +647 1 3 -1.0500000000000000e+00 1.2542455852135834e+00 3.7373752120048742e+00 -5.9607992485127665e+00 0 0 1 +648 1 3 -1.0500000000000000e+00 4.9971716802184414e+00 1.5601454347120267e+00 -5.9587058378165576e+00 0 0 1 +649 1 3 -1.0500000000000000e+00 3.8440041612115703e+00 3.8861931285291931e+00 -6.1503945630703374e+00 0 0 1 +650 1 5 4.2499999999999999e-01 2.0965664266306856e+00 8.6640571709351022e-01 -8.0457855564755221e+00 0 0 1 +651 1 1 1.5750000000000000e+00 3.5114550282895003e+00 5.7907578289563908e+00 9.1936291799320600e+00 0 0 0 +652 1 2 2.1000000000000001e+00 2.4780321755723715e+00 4.5623640127866523e+00 -6.4424127795872970e+00 0 0 1 +653 1 2 2.1000000000000001e+00 2.5576727978274061e+00 7.5173398896816757e+00 -6.4345086110749499e+00 0 0 1 +654 1 3 -1.0500000000000000e+00 2.3368431861690446e+00 4.6333600597891369e+00 -8.0605492211226508e+00 0 0 1 +655 1 3 -1.0500000000000000e+00 2.6923826235310759e+00 7.4246193194823391e+00 -8.0594146702702183e+00 0 0 1 +656 1 4 -9.4999999999999996e-01 5.2115829731287189e+00 6.2281267873758885e+00 -8.1893654320210807e+00 0 0 1 +657 1 3 -1.0500000000000000e+00 3.8624444953521344e+00 8.2202786364954399e+00 -5.9607758363894661e+00 0 0 1 +658 1 3 -1.0500000000000000e+00 2.4453330767289607e+00 6.0430641736627777e+00 -5.9587080529496408e+00 0 0 1 +659 1 3 -1.0500000000000000e+00 1.2921732996260165e+00 8.3691407396663671e+00 -6.1504119881455370e+00 0 0 1 +660 1 5 4.2499999999999999e-01 4.7046988428178977e+00 5.3493130177618120e+00 -8.0457432166301501e+00 0 0 1 +661 1 1 1.5750000000000000e+00 9.1939897374337853e-01 7.2944681040671533e+00 9.1931409599603455e+00 0 0 0 +662 1 2 2.1000000000000001e+00 1.3038993986497616e-01 -7.9297399937615864e-02 6.4359157158029880e+00 0 0 0 +663 1 2 2.1000000000000001e+00 1.0709548741821351e-01 5.9314795901314916e+00 6.4280530942119469e+00 0 0 0 +664 1 3 -1.0500000000000000e+00 3.2769702380019616e-01 8.8153278361017087e+00 8.0541328072809932e+00 0 0 0 +665 1 3 -1.0500000000000000e+00 -2.7577048002024540e-02 6.0244668918843125e+00 8.0528534019165114e+00 0 0 0 +666 1 4 -9.4999999999999996e-01 2.6131161534111662e+00 7.2207287036538688e+00 8.1828861539669902e+00 0 0 0 +667 1 3 -1.0500000000000000e+00 3.9622586469205352e+00 5.2286377281547125e+00 5.9541122763207728e+00 0 0 0 +668 1 3 -1.0500000000000000e+00 2.1920683743605807e-01 7.4058249891069572e+00 5.9524118713538332e+00 0 0 0 +669 1 3 -1.0500000000000000e+00 1.3725990807979294e+00 5.0798240702830135e+00 6.1439110162023720e+00 0 0 0 +670 1 5 4.2499999999999999e-01 3.1199732920356418e+00 8.0995675675041703e+00 8.0391592725870282e+00 0 0 0 +671 1 1 1.5750000000000000e+00 -1.6887626179515607e+00 2.8115295078010867e+00 9.1931424252045630e+00 0 0 0 +672 1 2 2.1000000000000001e+00 2.7385869519563499e+00 4.4035977810533353e+00 6.4359159181916219e+00 0 0 0 +673 1 2 2.1000000000000001e+00 2.6589194294892575e+00 1.4485953760994725e+00 6.4280582079700412e+00 0 0 0 +674 1 3 -1.0500000000000000e+00 2.8795450934696767e+00 4.3324405226142382e+00 8.0541191847946116e+00 0 0 0 +675 1 3 -1.0500000000000000e+00 2.5242342524813459e+00 1.5415689319063191e+00 8.0528783307282445e+00 0 0 0 +676 1 4 -9.4999999999999996e-01 4.8784689801895098e-03 2.7377462205787744e+00 8.1828769724994572e+00 0 0 0 +677 1 3 -1.0500000000000000e+00 1.3540645414120398e+00 7.4573621369630771e-01 5.9540951763794290e+00 0 0 0 +678 1 3 -1.0500000000000000e+00 2.7710487894445812e+00 2.9229363552675593e+00 5.9524016589185003e+00 0 0 0 +679 1 3 -1.0500000000000000e+00 3.9244363315488222e+00 5.9687068067378490e-01 6.1439283855687208e+00 0 0 0 +680 1 5 4.2499999999999999e-01 5.1182958888196950e-01 3.6166698539281406e+00 8.0390353352204258e+00 0 0 0 +681 1 1 1.5750000000000000e+00 6.0632942270537633e+00 1.3078169876851220e+00 9.1936311772266670e+00 0 0 0 +682 1 2 2.1000000000000001e+00 -1.0393798325235846e+01 9.0452739485367424e+00 -6.4424156068686536e+00 1 0 1 +683 1 2 2.1000000000000001e+00 -1.0370532688021308e+01 3.0344580928070393e+00 -6.4344922061203995e+00 1 0 1 +684 1 3 -1.0500000000000000e+00 1.0048686020539265e+01 1.5046462355047652e-01 -8.0605545916265591e+00 0 0 1 +685 1 3 -1.0500000000000000e+00 -1.0235804675645195e+01 2.9417358723974196e+00 -8.0593999402563039e+00 1 0 1 +686 1 4 -9.4999999999999996e-01 7.7633395990307577e+00 1.7451343070668237e+00 -8.1893820944806723e+00 0 0 1 +687 1 3 -1.0500000000000000e+00 6.4142512718313398e+00 3.7373784423628784e+00 -5.9607944539472024e+00 0 0 1 +688 1 3 -1.0500000000000000e+00 -1.0482832407337161e+01 1.5601299826680055e+00 -5.9586900611972622e+00 1 0 1 +689 1 3 -1.0500000000000000e+00 9.0040166486961724e+00 3.8861879123933356e+00 -6.1503979527282322e+00 0 0 1 +690 1 5 4.2499999999999999e-01 7.2565522149876038e+00 8.6639701182161843e-01 -8.0459259751794452e+00 0 0 1 +691 1 1 1.5750000000000000e+00 -1.1968537431183220e+01 5.7907580951124764e+00 9.1936264813234629e+00 1 0 0 +692 1 2 2.1000000000000001e+00 7.6380264848568480e+00 4.5623772756766172e+00 -6.4424042946661455e+00 0 0 1 +693 1 2 2.1000000000000001e+00 7.7176486578355963e+00 7.5173331294719183e+00 -6.4345083071021740e+00 0 0 1 +694 1 3 -1.0500000000000000e+00 7.4968492694646329e+00 4.6333567441294718e+00 -8.0605633819113667e+00 0 0 1 +695 1 3 -1.0500000000000000e+00 7.8523804276681837e+00 7.4246294275852094e+00 -8.0594213971891069e+00 0 0 1 +696 1 4 -9.4999999999999996e-01 -1.0268423694159754e+01 6.2281174442746980e+00 -8.1893456261947950e+00 1 0 1 +697 1 3 -1.0500000000000000e+00 9.0224907290535974e+00 8.2203025512221188e+00 -5.9607878799717344e+00 0 0 1 +698 1 3 -1.0500000000000000e+00 7.6053307981435196e+00 6.0430347893748895e+00 -5.9587019740450744e+00 0 0 1 +699 1 3 -1.0500000000000000e+00 6.4521656412247061e+00 8.3691447635715939e+00 -6.1504109506876619e+00 0 0 1 +700 1 5 4.2499999999999999e-01 9.8647336224214257e+00 5.3493476067839048e+00 -8.0456403223888646e+00 0 0 1 +701 1 1 1.5750000000000000e+00 6.0794078571688708e+00 7.2944672054170034e+00 9.1931387604710437e+00 0 0 0 +702 1 2 2.1000000000000001e+00 5.2903927590288387e+00 -7.9312034344852123e-02 6.4359061568910381e+00 0 0 0 +703 1 2 2.1000000000000001e+00 5.2671187145264451e+00 5.9314885138761895e+00 6.4280540558924795e+00 0 0 0 +704 1 3 -1.0500000000000000e+00 5.4876891838999047e+00 8.8153320262813786e+00 8.0541505226321348e+00 0 0 0 +705 1 3 -1.0500000000000000e+00 5.1324255766353062e+00 6.0244559010705814e+00 8.0528602469110595e+00 0 0 0 +706 1 4 -9.4999999999999996e-01 -1.2866893134241742e+01 7.2207151463837640e+00 8.1829043644805566e+00 1 0 0 +707 1 3 -1.0500000000000000e+00 -1.1517695582926537e+01 5.2286614618147631e+00 5.9541014619513177e+00 1 0 0 +708 1 3 -1.0500000000000000e+00 5.3792088967617762e+00 7.4058530000867115e+00 5.9524066869292191e+00 0 0 0 +709 1 3 -1.0500000000000000e+00 6.5326055526273592e+00 5.0798202391399414e+00 6.1439090309796480e+00 0 0 0 +710 1 5 4.2499999999999999e-01 -1.2359993555416519e+01 8.0996018552035594e+00 8.0392491603506926e+00 1 0 0 +711 1 1 1.5750000000000000e+00 3.4712234255278887e+00 2.8115394997158880e+00 9.1931391128052944e+00 0 0 0 +712 1 2 2.1000000000000001e+00 -1.2741436473488831e+01 4.4035966072164179e+00 6.4359068114368210e+00 1 0 0 +713 1 2 2.1000000000000001e+00 -1.2821086026369231e+01 1.4486074172151717e+00 6.4280700878493633e+00 1 0 0 +714 1 3 -1.0500000000000000e+00 -1.2600468968641490e+01 4.3324381244139616e+00 8.0541460499971507e+00 1 0 0 +715 1 3 -1.0500000000000000e+00 -1.2955762910609096e+01 1.5415738718932701e+00 8.0528750796115318e+00 1 0 0 +716 1 4 -9.4999999999999996e-01 5.1649091672213814e+00 2.7377878492092051e+00 8.1828935067407187e+00 0 0 0 +717 1 3 -1.0500000000000000e+00 6.5140624838503562e+00 7.4573449160736516e-01 5.9540890408837548e+00 0 0 0 +718 1 3 -1.0500000000000000e+00 -1.2708954990084692e+01 2.9229186261097801e+00 5.9524185176229256e+00 1 0 0 +719 1 3 -1.0500000000000000e+00 -1.1555552596604405e+01 5.9686666841561120e-01 6.1439252012806840e+00 1 0 0 +720 1 5 4.2499999999999999e-01 5.6718460531567594e+00 3.6166822258108873e+00 8.0391876250502783e+00 0 0 0 +721 1 1 1.5750000000000000e+00 -9.4167199060881881e+00 1.3078268191493692e+00 9.1936284569148015e+00 1 0 0 +722 1 2 2.1000000000000001e+00 -5.2337744657239433e+00 9.0452766042384738e+00 -6.4424045702369455e+00 1 0 1 +723 1 2 2.1000000000000001e+00 -5.2105281225591042e+00 3.0344444952698204e+00 -6.4345035089905984e+00 1 0 1 +724 1 3 -1.0500000000000000e+00 -5.4312992074936357e+00 1.5046681141750895e-01 -8.0605839113224356e+00 1 0 1 +725 1 3 -1.0500000000000000e+00 -5.0758078374764404e+00 2.9417318484454675e+00 -8.0593973266164873e+00 1 0 1 +726 1 4 -9.4999999999999996e-01 -7.7166293890810103e+00 1.7451757670354233e+00 -8.1893673368413982e+00 1 0 1 +727 1 3 -1.0500000000000000e+00 -9.0657538566382421e+00 3.7373757159528864e+00 -5.9607990251074803e+00 1 0 1 +728 1 3 -1.0500000000000000e+00 -5.3228288100664747e+00 1.5601455206964303e+00 -5.9587064079961714e+00 1 0 1 +729 1 3 -1.0500000000000000e+00 -6.4759962422743165e+00 3.8861930601011174e+00 -6.1503948993679884e+00 1 0 1 +730 1 5 4.2499999999999999e-01 -8.2234331102634997e+00 8.6640653809297419e-01 -8.0457837360048821e+00 1 0 1 +731 1 1 1.5750000000000000e+00 -6.8085449284088639e+00 5.7907577807183372e+00 9.1936293269548521e+00 1 0 0 +732 1 2 2.1000000000000001e+00 -7.8419680626851189e+00 4.5623634416592758e+00 -6.4424126333628751e+00 1 0 1 +733 1 2 2.1000000000000001e+00 -7.7623275299073544e+00 7.5173406513668297e+00 -6.4345089088641538e+00 1 0 1 +734 1 3 -1.0500000000000000e+00 -7.9831563836472403e+00 4.6333602950605197e+00 -8.0605491278584473e+00 1 0 1 +735 1 3 -1.0500000000000000e+00 -7.6276171712668432e+00 7.4246189825803306e+00 -8.0594145553904770e+00 1 0 1 +736 1 4 -9.4999999999999996e-01 -5.1084172118972777e+00 6.2281269736840663e+00 -8.1893656974078635e+00 1 0 1 +737 1 3 -1.0500000000000000e+00 -6.4575553159047985e+00 8.2202787726173803e+00 -5.9607759162796174e+00 1 0 1 +738 1 3 -1.0500000000000000e+00 -7.8746669235491940e+00 6.0430635684913305e+00 -5.9587081543805747e+00 1 0 1 +739 1 3 -1.0500000000000000e+00 -9.0278274510389611e+00 8.3691408883945471e+00 -6.1504119619142976e+00 1 0 1 +740 1 5 4.2499999999999999e-01 -5.6153013914286491e+00 5.3493123886781433e+00 -8.0457448175864990e+00 1 0 1 +741 1 1 1.5750000000000000e+00 -9.4006010736587182e+00 7.2944682033683108e+00 9.1931405770212429e+00 1 0 0 +742 1 2 2.1000000000000001e+00 -1.0189610402198802e+01 -7.9297605759123257e-02 6.4359160010201411e+00 1 0 0 +743 1 2 2.1000000000000001e+00 -1.0212904137937610e+01 5.9314797115273628e+00 6.4280531027538306e+00 1 0 0 +744 1 3 -1.0500000000000000e+00 -9.9923029717657226e+00 8.8153286205910888e+00 8.0541331394482896e+00 1 0 0 +745 1 3 -1.0500000000000000e+00 -1.0347577370841730e+01 6.0244660873837574e+00 8.0528534336309434e+00 1 0 0 +746 1 4 -9.4999999999999996e-01 -7.7068834885402087e+00 7.2207286744038370e+00 8.1828858968542733e+00 1 0 0 +747 1 3 -1.0500000000000000e+00 -6.3577402971397685e+00 5.2286383860826824e+00 5.9541124938145380e+00 1 0 0 +748 1 3 -1.0500000000000000e+00 -1.0100793183120766e+01 7.4058245081335947e+00 5.9524106541055115e+00 1 0 0 +749 1 3 -1.0500000000000000e+00 -8.9474022065604224e+00 5.0798241454221369e+00 6.1439110956024354e+00 1 0 0 +750 1 5 4.2499999999999999e-01 -7.2000270353828046e+00 8.0995672068003088e+00 8.0391580946381538e+00 1 0 0 +751 1 1 1.5750000000000000e+00 -1.2008762881451348e+01 2.8115295177180428e+00 9.1931425674069622e+00 1 0 0 +752 1 2 2.1000000000000001e+00 -7.5814135479309908e+00 4.4035983789351896e+00 6.4359165483385254e+00 1 0 0 +753 1 2 2.1000000000000001e+00 -7.6610808670997494e+00 1.4485945780712797e+00 6.4280582613292712e+00 1 0 0 +754 1 3 -1.0500000000000000e+00 -7.4404546055668366e+00 4.3324402056750237e+00 8.0541182772999065e+00 1 0 0 +755 1 3 -1.0500000000000000e+00 -7.7957660342353634e+00 1.5415692603738904e+00 8.0528775182214503e+00 1 0 0 +756 1 4 -9.4999999999999996e-01 -1.0315122227353797e+01 2.7377447118390101e+00 8.1828767909309512e+00 1 0 0 +757 1 3 -1.0500000000000000e+00 -8.9659352915333912e+00 7.4573683553695247e-01 5.9540956560325071e+00 1 0 0 +758 1 3 -1.0500000000000000e+00 -7.5489512806955084e+00 2.9229361730432970e+00 5.9524018601671909e+00 1 0 0 +759 1 3 -1.0500000000000000e+00 -6.3955632518685768e+00 5.9687042658164202e-01 6.1439287069185120e+00 1 0 0 +760 1 5 4.2499999999999999e-01 -9.8081700960310911e+00 3.6166702227703560e+00 8.0390328438422074e+00 1 0 0 +761 1 1 1.5750000000000000e+00 -4.2567053371850658e+00 1.3078168179231042e+00 9.1936310535964232e+00 1 0 0 +762 1 2 2.1000000000000001e+00 -7.3798358768387473e-02 9.0452733241225367e+00 -6.4424155682759778e+00 1 0 1 +763 1 2 2.1000000000000001e+00 -5.0532229357781233e-02 3.0344580784693349e+00 -6.4344918700685572e+00 1 0 1 +764 1 3 -1.0500000000000000e+00 -2.7131416236533745e-01 1.5046495859890285e-01 -8.0605544059037157e+00 1 0 1 +765 1 3 -1.0500000000000000e+00 8.4195332462293493e-02 2.9417357818207392e+00 -8.0593997996762017e+00 1 0 1 +766 1 4 -9.4999999999999996e-01 -2.5566610233707436e+00 1.7451330035208805e+00 -8.1893824664560277e+00 1 0 1 +767 1 3 -1.0500000000000000e+00 -3.9057480740250670e+00 3.7373787164792880e+00 -5.9607940658222685e+00 1 0 1 +768 1 3 -1.0500000000000000e+00 -1.6283268367977044e-01 1.5601301436753872e+00 -5.9586903754265217e+00 1 0 1 +769 1 3 -1.0500000000000000e+00 -1.3159834872646030e+00 3.8861877175565063e+00 -6.1503980963921077e+00 1 0 1 +770 1 5 4.2499999999999999e-01 -3.0634476704969611e+00 8.6639700750263771e-01 -8.0459289853123099e+00 1 0 1 +771 1 1 1.5750000000000000e+00 -1.6485375220706722e+00 5.7907579502462809e+00 9.1936265404422031e+00 1 0 0 +772 1 2 2.1000000000000001e+00 -2.6819735576082735e+00 4.5623781023095979e+00 -6.4424040572249073e+00 1 0 1 +773 1 2 2.1000000000000001e+00 -2.6023515605367979e+00 7.5173327298043446e+00 -6.4345082402300129e+00 1 0 1 +774 1 3 -1.0500000000000000e+00 -2.8231506835232665e+00 4.6333563194435925e+00 -8.0605641951789604e+00 1 0 1 +775 1 3 -1.0500000000000000e+00 -2.4676198319304250e+00 7.4246300333344308e+00 -8.0594222945481242e+00 1 0 1 +776 1 4 -9.4999999999999996e-01 5.1576495784171783e-02 6.2281174409833078e+00 -8.1893454451251166e+00 1 0 1 +777 1 3 -1.0500000000000000e+00 -1.2975095016776308e+00 8.2203029875449154e+00 -5.9607878139978627e+00 1 0 1 +778 1 3 -1.0500000000000000e+00 -2.7146694253441410e+00 6.0430341006248725e+00 -5.9587013238385174e+00 1 0 1 +779 1 3 -1.0500000000000000e+00 -3.8678341546705104e+00 8.3691444919325306e+00 -6.1504110733339727e+00 1 0 1 +780 1 5 4.2499999999999999e-01 -4.5526617430967775e-01 5.3493482680335944e+00 -8.0456383324324694e+00 1 0 1 +781 1 1 1.5750000000000000e+00 -4.2405919059825807e+00 7.2944670077944807e+00 9.1931388109336041e+00 1 0 0 +782 1 2 2.1000000000000001e+00 -5.0296064030418073e+00 -7.9312429721781541e-02 6.4359061250102680e+00 1 0 0 +783 1 2 2.1000000000000001e+00 -5.0528803208991677e+00 5.9314885847207393e+00 6.4280541425652125e+00 1 0 0 +784 1 3 -1.0500000000000000e+00 -4.8323113190408655e+00 8.8153320489722837e+00 8.0541507220343149e+00 1 0 0 +785 1 3 -1.0500000000000000e+00 -5.1875750890510588e+00 6.0244559180381110e+00 8.0528596115841111e+00 1 0 0 +786 1 4 -9.4999999999999996e-01 -2.5468930396501683e+00 7.2207149872186704e+00 8.1829042004208787e+00 1 0 0 +787 1 3 -1.0500000000000000e+00 -1.1976965541013911e+00 5.2286614070351156e+00 5.9541011082395521e+00 1 0 0 +788 1 3 -1.0500000000000000e+00 -4.9407917338772620e+00 7.4058524302343827e+00 5.9524067025542333e+00 1 0 0 +789 1 3 -1.0500000000000000e+00 -3.7873946085238082e+00 5.0798202478013827e+00 6.1439086823543967e+00 1 0 0 +790 1 5 4.2499999999999999e-01 -2.0399936634126092e+00 8.0996016485694859e+00 8.0392480188451927e+00 1 0 0 +791 1 1 1.5750000000000000e+00 -6.8487764459721472e+00 2.8115396349174162e+00 9.1931393353000779e+00 1 0 0 +792 1 2 2.1000000000000001e+00 -2.4214360684733940e+00 4.4035963531915776e+00 6.4359069157849582e+00 1 0 0 +793 1 2 2.1000000000000001e+00 -2.5010867592299606e+00 1.4486079821071627e+00 6.4280700334665895e+00 1 0 0 +794 1 3 -1.0500000000000000e+00 -2.2804693176190796e+00 4.3324382110458508e+00 8.0541466060331786e+00 1 0 0 +795 1 3 -1.0500000000000000e+00 -2.6357629333121757e+00 1.5415738251322431e+00 8.0528749502136669e+00 1 0 0 +796 1 4 -9.4999999999999996e-01 -5.1550909689645312e+00 2.7377879547736299e+00 8.1828937813504332e+00 1 0 0 +797 1 3 -1.0500000000000000e+00 -3.8059367645404496e+00 7.4573545262324359e-01 5.9540888558950602e+00 1 0 0 +798 1 3 -1.0500000000000000e+00 -2.3889553911064834e+00 2.9229182779601004e+00 5.9524183742338437e+00 1 0 0 +799 1 3 -1.0500000000000000e+00 -1.2355527417253249e+00 5.9686629625387155e-01 6.1439250256775200e+00 1 0 0 +800 1 5 4.2499999999999999e-01 -4.6481532735579094e+00 3.6166830920668787e+00 8.0391899192038352e+00 1 0 0 +801 1 1 1.5750000000000000e+00 9.5960721862191178e-01 1.0273669203704241e+01 9.1936235733136655e+00 0 0 0 +802 1 2 2.1000000000000001e+00 4.9172083055255325e+00 -1.7852191623671651e+01 -6.4424003148067897e+00 0 1 1 +803 1 2 2.1000000000000001e+00 5.1658109241490635e+00 1.2000275388808074e+01 -6.4345007360704409e+00 0 0 1 +804 1 3 -1.0500000000000000e+00 4.9450244688133118e+00 9.1162949204304589e+00 -8.0605632730520096e+00 0 0 1 +805 1 3 -1.0500000000000000e+00 5.3005308774925517e+00 1.1907548980836420e+01 -8.0594017059932295e+00 0 0 1 +806 1 4 -9.4999999999999996e-01 2.6597454135294925e+00 1.0711060731609876e+01 -8.1893222259048226e+00 0 0 1 +807 1 3 -1.0500000000000000e+00 1.3105929168482859e+00 1.2703195772710561e+01 -5.9607978618737851e+00 0 0 1 +808 1 3 -1.0500000000000000e+00 5.0535126422700269e+00 1.0525967976026514e+01 -5.9587374189296218e+00 0 0 1 +809 1 3 -1.0500000000000000e+00 3.9003367713006512e+00 1.2852015907184782e+01 -6.1503929107381827e+00 0 0 1 +810 1 5 4.2499999999999999e-01 2.1529230807864241e+00 9.8323236639573999e+00 -8.0454353340627449e+00 0 0 1 +811 1 1 1.5750000000000000e+00 3.5677901403638028e+00 1.4756558886709637e+01 9.1936320859504761e+00 0 0 0 +812 1 2 2.1000000000000001e+00 2.5343724058499628e+00 1.3528195803657599e+01 -6.4424233387050833e+00 0 0 1 +813 1 2 2.1000000000000001e+00 2.6139913107597703e+00 1.6483175576855384e+01 -6.4345033330073518e+00 0 0 1 +814 1 3 -1.0500000000000000e+00 2.3931907288388619e+00 1.3599192072250563e+01 -8.0605653726222926e+00 0 0 1 +815 1 3 -1.0500000000000000e+00 2.7487038780850757e+00 1.6390457170443742e+01 -8.0594014632146163e+00 0 0 1 +816 1 4 -9.4999999999999996e-01 5.2678674489775172e+00 1.5193891941576492e+01 -8.1893953522173568e+00 0 0 1 +817 1 3 -1.0500000000000000e+00 3.9187441878934699e+00 1.7186101345028060e+01 -5.9607852712427771e+00 0 0 1 +818 1 3 -1.0500000000000000e+00 2.5016682244761341e+00 1.5008886897788546e+01 -5.9586911872320503e+00 0 0 1 +819 1 3 -1.0500000000000000e+00 1.3485131765279306e+00 1.7334940064883479e+01 -6.1504041699538501e+00 0 0 1 +820 1 5 4.2499999999999999e-01 4.7610305469518792e+00 1.4315086371947789e+01 -8.0459836447046609e+00 0 0 1 +821 1 1 1.5750000000000000e+00 9.7572650104669378e-01 1.6260281732774981e+01 9.1931398694629891e+00 0 0 0 +822 1 2 2.1000000000000001e+00 1.8672671622704407e-01 8.8865134574184275e+00 6.4359252403327680e+00 0 0 0 +823 1 2 2.1000000000000001e+00 1.6341323909156813e-01 1.4897327838108385e+01 6.4280628738807160e+00 0 0 0 +824 1 3 -1.0500000000000000e+00 1.5869811845495363e-01 -1.8082123015369124e+01 8.0541340213658152e+00 0 1 0 +825 1 3 -1.0500000000000000e+00 2.8742433885017959e-02 1.4990304244778233e+01 8.0528666545587271e+00 0 0 0 +826 1 4 -9.4999999999999996e-01 2.6694272128344245e+00 1.6186542002547892e+01 8.1828957582626032e+00 0 0 0 +827 1 3 -1.0500000000000000e+00 4.0185585050563635e+00 1.4194457856414292e+01 5.9541011149118788e+00 0 0 0 +828 1 3 -1.0500000000000000e+00 2.7554898326217625e-01 1.6371647903721165e+01 5.9524005485591456e+00 0 0 0 +829 1 3 -1.0500000000000000e+00 1.4289385783169752e+00 1.4045613821719037e+01 6.1439242276787418e+00 0 0 0 +830 1 5 4.2499999999999999e-01 3.1763286179058490e+00 1.7065430306293440e+01 8.0392248483087627e+00 0 0 0 +831 1 1 1.5750000000000000e+00 -1.6324184683740341e+00 1.1777344934266068e+01 9.1931465772030379e+00 0 0 0 +832 1 2 2.1000000000000001e+00 2.7949109368093250e+00 1.3369431615951214e+01 6.4359123446196520e+00 0 0 0 +833 1 2 2.1000000000000001e+00 2.7152603396729695e+00 1.0414397731227350e+01 6.4280500078867284e+00 0 0 0 +834 1 3 -1.0500000000000000e+00 2.9358844870702256e+00 1.3298249254921139e+01 8.0541035265692571e+00 0 0 0 +835 1 3 -1.0500000000000000e+00 2.5805749833761542e+00 1.0507387417059693e+01 8.0528735429538472e+00 0 0 0 +836 1 4 -9.4999999999999996e-01 6.1197499880652373e-02 1.1703528856756993e+01 8.1828384666384260e+00 0 0 0 +837 1 3 -1.0500000000000000e+00 1.4104102567525914e+00 9.7115620528564612e+00 5.9541021771064706e+00 0 0 0 +838 1 3 -1.0500000000000000e+00 2.8273745913960777e+00 1.1888758720918936e+01 5.9524302538497906e+00 0 0 0 +839 1 3 -1.0500000000000000e+00 3.9807696072751568e+00 9.5627134385235948e+00 6.1439195726972784e+00 0 0 0 +840 1 5 4.2499999999999999e-01 5.6813568547824111e-01 1.2582401681601350e+01 8.0387418936318475e+00 0 0 0 +841 1 1 1.5750000000000000e+00 6.1196215253814046e+00 1.0273659065047806e+01 9.1936258533248534e+00 0 0 0 +842 1 2 2.1000000000000001e+00 -1.0562814009027809e+01 -1.7852194770053313e+01 -6.4424105685276851e+00 1 1 1 +843 1 2 2.1000000000000001e+00 -1.0314192648491979e+01 1.2000288960951057e+01 -6.4344887365136625e+00 1 0 1 +844 1 3 -1.0500000000000000e+00 1.0105009678123249e+01 9.1162929018207564e+00 -8.0605338552440937e+00 0 0 1 +845 1 3 -1.0500000000000000e+00 -1.0179466880668443e+01 1.1907552881889412e+01 -8.0594043468605676e+00 1 0 1 +846 1 4 -9.4999999999999996e-01 7.8197150885211819e+00 1.0711020034930083e+01 -8.1893365530719642e+00 0 0 1 +847 1 3 -1.0500000000000000e+00 6.4705998763924484e+00 1.2703199920926114e+01 -5.9607930505693743e+00 0 0 1 +848 1 3 -1.0500000000000000e+00 -1.0426491548728604e+01 1.0525953700197832e+01 -5.9587210876857588e+00 1 0 1 +849 1 3 -1.0500000000000000e+00 9.0603500318690493e+00 1.2852009950045630e+01 -6.1503965426825715e+00 0 0 1 +850 1 5 4.2499999999999999e-01 7.3129093231943401e+00 9.8323158297765794e+00 -8.0455729433718481e+00 0 0 1 +851 1 1 1.5750000000000000e+00 -1.1912201911242379e+01 1.4756558626125500e+01 9.1936299374457917e+00 1 0 0 +852 1 2 2.1000000000000001e+00 7.6943659531364794e+00 1.3528208886055431e+01 -6.4424143301466863e+00 0 0 1 +853 1 2 2.1000000000000001e+00 7.7739676680323946e+00 1.6483168696691120e+01 -6.4345034954359610e+00 0 0 1 +854 1 3 -1.0500000000000000e+00 7.5531973024030030e+00 1.3599188471640346e+01 -8.0605797041230307e+00 0 0 1 +855 1 3 -1.0500000000000000e+00 7.9087020351309256e+00 1.6390467445460896e+01 -8.0594079096168336e+00 0 0 1 +856 1 4 -9.4999999999999996e-01 -1.0212139335865229e+01 1.5193882091436695e+01 -8.1893761679918828e+00 1 0 1 +857 1 3 -1.0500000000000000e+00 9.0787892522491873e+00 1.7186124575197912e+01 -5.9607974326211624e+00 0 0 1 +858 1 3 -1.0500000000000000e+00 7.6616656495931785e+00 1.5008857806803714e+01 -5.9586855554315239e+00 0 0 1 +859 1 3 -1.0500000000000000e+00 6.5085065607252339e+00 1.7334943758700970e+01 -6.1504023223690254e+00 0 0 1 +860 1 5 4.2499999999999999e-01 9.9210652194241220e+00 1.4315120680602522e+01 -8.0458834643735155e+00 0 0 1 +861 1 1 1.5750000000000000e+00 6.1357349670429358e+00 1.6260281068792370e+01 9.1931373680824571e+00 0 0 0 +862 1 2 2.1000000000000001e+00 5.3467301429260417e+00 8.8864991034834802e+00 6.4359154980254800e+00 0 0 0 +863 1 2 2.1000000000000001e+00 5.3234375680067387e+00 1.4897337020707621e+01 6.4280633305033579e+00 0 0 0 +864 1 3 -1.0500000000000000e+00 5.3186906165474923e+00 -1.8082119281913194e+01 8.0541512151208217e+00 0 1 0 +865 1 3 -1.0500000000000000e+00 5.1887452446427620e+00 1.4990293685008570e+01 8.0528738710979937e+00 0 0 0 +866 1 4 -9.4999999999999996e-01 -1.2810582246898260e+01 1.6186528254419503e+01 8.1829142774136940e+00 1 0 0 +867 1 3 -1.0500000000000000e+00 -1.1461395078265998e+01 1.4194482279531240e+01 5.9540899004490573e+00 1 0 0 +868 1 3 -1.0500000000000000e+00 5.4355508226374880e+00 1.6371676240781067e+01 5.9523953371586007e+00 0 0 0 +869 1 3 -1.0500000000000000e+00 6.5889448393182057e+00 1.4045610487796125e+01 6.1439231486978052e+00 0 0 0 +870 1 5 4.2499999999999999e-01 -1.2303637921787351e+01 1.7065464446927333e+01 8.0393139102372757e+00 1 0 0 +871 1 1 1.5750000000000000e+00 3.5275677694768159e+00 1.1777354695333322e+01 9.1931437178279722e+00 0 0 0 +872 1 2 2.1000000000000001e+00 -1.2685112265527499e+01 1.3369430390314744e+01 6.4359024875393231e+00 1 0 0 +873 1 2 2.1000000000000001e+00 -1.2764745750720230e+01 1.0414410392944081e+01 6.4280618196758432e+00 1 0 0 +874 1 3 -1.0500000000000000e+00 -1.2544129418050623e+01 1.3298246737339653e+01 8.0541308893949868e+00 1 0 0 +875 1 3 -1.0500000000000000e+00 -1.2899422299851542e+01 1.0507392314703441e+01 8.0528703655478253e+00 1 0 0 +876 1 4 -9.4999999999999996e-01 5.2212278834502932e+00 1.1703569772888418e+01 8.1828544574580064e+00 0 0 0 +877 1 3 -1.0500000000000000e+00 6.5704071848659780e+00 9.7115602039361448e+00 5.9540954146707854e+00 0 0 0 +878 1 3 -1.0500000000000000e+00 -1.2652629524673211e+01 1.1888740289825776e+01 5.9524475845137914e+00 1 0 0 +879 1 3 -1.0500000000000000e+00 -1.1499218746205949e+01 9.5627087106832143e+00 6.1439160615276585e+00 1 0 0 +880 1 5 4.2499999999999999e-01 5.7281515933265581e+00 1.2582412438419141e+01 8.0388892666496652e+00 0 0 0 +881 1 1 1.5750000000000000e+00 -9.3603927864488465e+00 1.0273669083913415e+01 9.1936233661194393e+00 1 0 0 +882 1 2 2.1000000000000001e+00 -5.4027908311748014e+00 -1.7852191591920860e+01 -6.4423999875116174e+00 1 1 1 +883 1 2 2.1000000000000001e+00 -5.1541886950179352e+00 1.2000275601569015e+01 -6.4345007553289859e+00 1 0 1 +884 1 3 -1.0500000000000000e+00 -5.3749756973895453e+00 9.1162952266749038e+00 -8.0605627427916939e+00 1 0 1 +885 1 3 -1.0500000000000000e+00 -5.0194697033740354e+00 1.1907548341371790e+01 -8.0594018260737599e+00 1 0 1 +886 1 4 -9.4999999999999996e-01 -7.6602542409070491e+00 1.0711060750080897e+01 -8.1893221273874310e+00 1 0 1 +887 1 3 -1.0500000000000000e+00 -9.0094074701008555e+00 1.2703195909859126e+01 -5.9607981827342975e+00 1 0 1 +888 1 3 -1.0500000000000000e+00 -5.2664879046879927e+00 1.0525968292949354e+01 -5.9587382228044579e+00 1 0 1 +889 1 3 -1.0500000000000000e+00 -6.4196629439277020e+00 1.2852015502374297e+01 -6.1503932553102407e+00 1 0 1 +890 1 5 4.2499999999999999e-01 -8.1670767718813568e+00 9.8323240619096737e+00 -8.0454342284319758e+00 1 0 1 +891 1 1 1.5750000000000000e+00 -6.7522099413499017e+00 1.4756558947084972e+01 9.1936323727388007e+00 1 0 0 +892 1 2 2.1000000000000001e+00 -7.7856279740588574e+00 1.3528195363213435e+01 -6.4424232658091753e+00 1 0 1 +893 1 2 2.1000000000000001e+00 -7.7060087959671275e+00 1.6483175890169566e+01 -6.4345031930632031e+00 1 0 1 +894 1 3 -1.0500000000000000e+00 -7.9268092601655393e+00 1.3599192115246709e+01 -8.0605653924195604e+00 1 0 1 +895 1 3 -1.0500000000000000e+00 -7.5712960116532937e+00 1.6390457132414308e+01 -8.0594014597887931e+00 1 0 1 +896 1 4 -9.4999999999999996e-01 -5.0521325823369825e+00 1.5193892557836794e+01 -8.1893952534646299e+00 1 0 1 +897 1 3 -1.0500000000000000e+00 -6.4012557391469294e+00 1.7186101532233774e+01 -5.9607858793978696e+00 1 0 1 +898 1 3 -1.0500000000000000e+00 -7.8183317428747330e+00 1.5008887211419324e+01 -5.9586911269344274e+00 1 0 1 +899 1 3 -1.0500000000000000e+00 -8.9714872285006528e+00 1.7334939869012782e+01 -6.1504040245545895e+00 1 0 1 +900 1 5 4.2499999999999999e-01 -5.5589691759804651e+00 1.4315086850375383e+01 -8.0459819775647716e+00 1 0 1 +901 1 1 1.5750000000000000e+00 -9.3442733480072278e+00 1.6260281622445302e+01 9.1931395426557110e+00 1 0 0 +902 1 2 2.1000000000000001e+00 -1.0133273070639682e+01 8.8865135585351283e+00 6.4359254506516130e+00 1 0 0 +903 1 2 2.1000000000000001e+00 -1.0156586250533065e+01 1.4897327970275054e+01 6.4280630778184857e+00 1 0 0 +904 1 3 -1.0500000000000000e+00 -1.0161302019375981e+01 -1.8082122656764607e+01 8.0541343934514202e+00 1 1 0 +905 1 3 -1.0500000000000000e+00 -1.0291257777350937e+01 1.4990303857072181e+01 8.0528666793281509e+00 1 0 0 +906 1 4 -9.4999999999999996e-01 -7.6505730793458735e+00 1.6186540928105540e+01 8.1828953469210077e+00 1 0 0 +907 1 3 -1.0500000000000000e+00 -6.3014405501587794e+00 1.4194458390634342e+01 5.9541017585236222e+00 1 0 0 +908 1 3 -1.0500000000000000e+00 -1.0044451276249209e+01 1.6371648291125627e+01 5.9523999323485963e+00 1 0 0 +909 1 3 -1.0500000000000000e+00 -8.8910624691465792e+00 1.4045613984800305e+01 6.1439241727047040e+00 1 0 0 +910 1 5 4.2499999999999999e-01 -7.1436715781015101e+00 1.7065429938006378e+01 8.0392210249142231e+00 1 0 0 +911 1 1 1.5750000000000000e+00 -1.1952418365405634e+01 1.1777344769910933e+01 9.1931467279769166e+00 1 0 0 +912 1 2 2.1000000000000001e+00 -7.5250893067069100e+00 1.3369431895710402e+01 6.4359125458494333e+00 1 0 0 +913 1 2 2.1000000000000001e+00 -7.6047401369908787e+00 1.0414397698876499e+01 6.4280497411191835e+00 1 0 0 +914 1 3 -1.0500000000000000e+00 -7.3841152575290465e+00 1.3298249173792914e+01 8.0541030584957483e+00 1 0 0 +915 1 3 -1.0500000000000000e+00 -7.7394250224018784e+00 1.0507387430609697e+01 8.0528732915954180e+00 1 0 0 +916 1 4 -9.4999999999999996e-01 -1.0258802640316311e+01 1.1703528516691946e+01 8.1828385357148221e+00 1 0 0 +917 1 3 -1.0500000000000000e+00 -8.9095901142621763e+00 9.7115620830072906e+00 5.9541024500382438e+00 1 0 0 +918 1 3 -1.0500000000000000e+00 -7.4926254257397229e+00 1.1888758199297200e+01 5.9524304645907566e+00 1 0 0 +919 1 3 -1.0500000000000000e+00 -6.3392300077947583e+00 9.5627130728697161e+00 6.1439197965438819e+00 1 0 0 +920 1 5 4.2499999999999999e-01 -9.7518639894871963e+00 1.2582402105100961e+01 8.0387424963826071e+00 1 0 0 +921 1 1 1.5750000000000000e+00 -4.2003781666602471e+00 1.0273659178062957e+01 9.1936255865073093e+00 1 0 0 +922 1 2 2.1000000000000001e+00 -2.4281380657306251e-01 -1.7852194978795438e+01 -6.4424104817889924e+00 1 1 1 +923 1 2 2.1000000000000001e+00 5.8073311176265463e-03 1.2000289091306779e+01 -6.4344887684447798e+00 1 0 1 +924 1 3 -1.0500000000000000e+00 -2.1499032318097377e-01 9.1162934469930086e+00 -8.0605336122239901e+00 1 0 1 +925 1 3 -1.0500000000000000e+00 1.4053305155494300e-01 1.1907552348135759e+01 -8.0594038296133501e+00 1 0 1 +926 1 4 -9.4999999999999996e-01 -2.5002851790322218e+00 1.0711019049960040e+01 -8.1893367336811629e+00 1 0 1 +927 1 3 -1.0500000000000000e+00 -3.8493992000608142e+00 1.2703200254186580e+01 -5.9607924527654337e+00 1 0 1 +928 1 3 -1.0500000000000000e+00 -1.0649173895659203e-01 1.0525953880245513e+01 -5.9587217128014212e+00 1 0 1 +929 1 3 -1.0500000000000000e+00 -1.2596509514345406e+00 1.2852010139898166e+01 -6.1503965479066123e+00 1 0 1 +930 1 5 4.2499999999999999e-01 -3.0070906737129794e+00 9.8323157767275227e+00 -8.0455750813439302e+00 1 0 1 +931 1 1 1.5750000000000000e+00 -1.5922020057366204e+00 1.4756558606205918e+01 9.1936300371528645e+00 1 0 0 +932 1 2 2.1000000000000001e+00 -2.6256342849090215e+00 1.3528209535884709e+01 -6.4424139428101448e+00 1 0 1 +933 1 2 2.1000000000000001e+00 -2.5460327371080291e+00 1.6483168361853000e+01 -6.4345035627546698e+00 1 0 1 +934 1 3 -1.0500000000000000e+00 -2.7668025513118506e+00 1.3599188282117982e+01 -8.0605804580563216e+00 1 0 1 +935 1 3 -1.0500000000000000e+00 -2.4112982996207268e+00 1.6390467789148698e+01 -8.0594086153186755e+00 1 0 1 +936 1 4 -9.4999999999999996e-01 1.0786065194175976e-01 1.5193881944029133e+01 -8.1893757702455225e+00 1 0 1 +937 1 3 -1.0500000000000000e+00 -1.2412111852687584e+00 1.7186124642348755e+01 -5.9607969511890113e+00 1 0 1 +938 1 3 -1.0500000000000000e+00 -2.6583342475974394e+00 1.5008857192020724e+01 -5.9586852469727489e+00 1 0 1 +939 1 3 -1.0500000000000000e+00 -3.8114931308841973e+00 1.7334943467465425e+01 -6.1504023276487931e+00 1 0 1 +940 1 5 4.2499999999999999e-01 -3.9893427220104982e-01 1.4315121673056158e+01 -8.0458809439058001e+00 1 0 1 +941 1 1 1.5750000000000000e+00 -4.1842647733189811e+00 1.6260280900738014e+01 9.1931373541656640e+00 1 0 0 +942 1 2 2.1000000000000001e+00 -4.9732694000809214e+00 8.8864994991107871e+00 6.4359156339852426e+00 1 0 0 +943 1 2 2.1000000000000001e+00 -4.9965619586163417e+00 1.4897336869865573e+01 6.4280633746036724e+00 1 0 0 +944 1 3 -1.0500000000000000e+00 -5.0013096301578557e+00 -1.8082119246981069e+01 8.0541515174107730e+00 1 1 0 +945 1 3 -1.0500000000000000e+00 -5.1312553567957622e+00 1.4990293360305930e+01 8.0528735880481079e+00 1 0 0 +946 1 4 -9.4999999999999996e-01 -2.4905823373432447e+00 1.6186527481653730e+01 8.1829144834701140e+00 1 0 0 +947 1 3 -1.0500000000000000e+00 -1.1413951190011318e+00 1.4194482448426054e+01 5.9540897749393551e+00 1 0 0 +948 1 3 -1.0500000000000000e+00 -4.8844497340440238e+00 1.6371676351109574e+01 5.9523950906844671e+00 1 0 0 +949 1 3 -1.0500000000000000e+00 -3.7310550651778556e+00 1.4045610398815395e+01 6.1439228472924778e+00 1 0 0 +950 1 5 4.2499999999999999e-01 -1.9836375134124715e+00 1.7065464974264582e+01 8.0393139158871101e+00 1 0 0 +951 1 1 1.5750000000000000e+00 -6.7924322972263633e+00 1.1777354850443714e+01 9.1931438146612265e+00 1 0 0 +952 1 2 2.1000000000000001e+00 -2.3651126781701990e+00 1.3369430006310449e+01 6.4359026051072608e+00 1 0 0 +953 1 2 2.1000000000000001e+00 -2.4447460827353300e+00 1.0414411083296347e+01 6.4280619889271122e+00 1 0 0 +954 1 3 -1.0500000000000000e+00 -2.2241294262454936e+00 1.3298247110263322e+01 8.0541315514418770e+00 1 0 0 +955 1 3 -1.0500000000000000e+00 -2.5794223333527002e+00 1.0507391785141490e+01 8.0528704188601807e+00 1 0 0 +956 1 4 -9.4999999999999996e-01 -5.0987720093367859e+00 1.1703570724197846e+01 8.1828547460418974e+00 1 0 0 +957 1 3 -1.0500000000000000e+00 -3.7495921260073386e+00 9.7115606887493051e+00 5.9540950468016760e+00 1 0 0 +958 1 3 -1.0500000000000000e+00 -2.3326296115329681e+00 1.1888740063197147e+01 5.9524471808153692e+00 1 0 0 +959 1 3 -1.0500000000000000e+00 -1.1792192073374927e+00 9.5627085299782664e+00 6.1439162617713929e+00 1 0 0 +960 1 5 4.2499999999999999e-01 -4.5918481348798545e+00 1.2582412837426194e+01 8.0388923615312642e+00 1 0 0 +961 1 1 1.5750000000000000e+00 7.9060983098709947e-01 -1.6623787873959273e+01 9.1936241221863249e+00 0 1 0 +962 1 2 2.1000000000000001e+00 4.9735388822158324e+00 -8.8863555261994307e+00 -6.4424092998091940e+00 0 1 1 +963 1 2 2.1000000000000001e+00 4.9968241249244869e+00 -1.4897218761397980e+01 -6.4345103916532667e+00 0 1 1 +964 1 3 -1.0500000000000000e+00 4.7760131551751499e+00 -1.7781192163992994e+01 -8.0605609776657161e+00 0 1 1 +965 1 3 -1.0500000000000000e+00 5.1315425565977346e+00 -1.4989934535773086e+01 -8.0594167673316317e+00 0 1 1 +966 1 4 -9.4999999999999996e-01 2.4907718354025317e+00 -1.6186388039551588e+01 -8.1893254397424453e+00 0 1 1 +967 1 3 -1.0500000000000000e+00 1.1416263133331963e+00 -1.4194270381621900e+01 -5.9607865702829335e+00 0 1 1 +968 1 3 -1.0500000000000000e+00 4.8845019877675924e+00 -1.6371500937997865e+01 -5.9587293889869883e+00 0 1 1 +969 1 3 -1.0500000000000000e+00 3.7313268130514974e+00 -1.4045419052787359e+01 -6.1504066950524141e+00 0 1 1 +970 1 5 4.2499999999999999e-01 1.9839009717795477e+00 -1.7065170720648808e+01 -8.0454457650585169e+00 0 1 1 +971 1 1 1.5750000000000000e+00 3.3987763835280393e+00 -1.2140905346190326e+01 9.1936279670263232e+00 0 1 0 +972 1 2 2.1000000000000001e+00 2.3653801838590205e+00 -1.3369283232827510e+01 -6.4424200206570612e+00 0 1 1 +973 1 2 2.1000000000000001e+00 2.4449786524018275e+00 -1.0414270762708139e+01 -6.4344947097414282e+00 0 1 1 +974 1 3 -1.0500000000000000e+00 2.2241844110169264e+00 -1.3298260551948676e+01 -8.0605520411220617e+00 0 1 1 +975 1 3 -1.0500000000000000e+00 2.5796912969422721e+00 -1.0507005922241635e+01 -8.0593940590064257e+00 0 1 1 +976 1 4 -9.4999999999999996e-01 5.0988702527267655e+00 -1.1703548043198262e+01 -8.1893609630806132e+00 0 1 1 +977 1 3 -1.0500000000000000e+00 3.7497226337578446e+00 -9.7113711982098554e+00 -5.9607926003920886e+00 0 1 1 +978 1 3 -1.0500000000000000e+00 2.3326731922370776e+00 -1.1888581465336951e+01 -5.9587182867267821e+00 0 1 1 +979 1 3 -1.0500000000000000e+00 1.1795119362153041e+00 -9.5625531841926961e+00 -6.1503935088776673e+00 0 1 1 +980 1 5 4.2499999999999999e-01 4.5920550844469084e+00 -1.2582296526462123e+01 -8.0457276875216497e+00 0 1 1 +981 1 1 1.5750000000000000e+00 8.0672847412836290e-01 -1.0637207792244846e+01 9.1931446898855285e+00 0 1 0 +982 1 2 2.1000000000000001e+00 1.7735241745661767e-02 -1.8010958050662659e+01 6.4359214102136661e+00 0 1 0 +983 1 2 2.1000000000000001e+00 -5.5984692701720462e-03 -1.2000144101042064e+01 6.4280608641863495e+00 0 1 0 +984 1 3 -1.0500000000000000e+00 2.1504497388601607e-01 -9.1163020892610103e+00 8.0541133501916313e+00 0 1 0 +985 1 3 -1.0500000000000000e+00 -1.4026752501513329e-01 -1.1907157403873917e+01 8.0528737619875344e+00 0 1 0 +986 1 4 -9.4999999999999996e-01 2.5003778817693600e+00 -1.0710992981939540e+01 8.1828509244580552e+00 0 1 0 +987 1 3 -1.0500000000000000e+00 3.8495354817159484e+00 -1.2703010397069693e+01 5.9540985576838814e+00 0 1 0 +988 1 3 -1.0500000000000000e+00 1.0654000383107132e-01 -1.0525822550974517e+01 5.9524296977026996e+00 0 1 0 +989 1 3 -1.0500000000000000e+00 1.2599376891911795e+00 -1.2851860677111500e+01 6.1439254063881670e+00 0 1 0 +990 1 5 4.2499999999999999e-01 3.0073045113687797e+00 -9.8321299051036668e+00 8.0388731267178173e+00 0 1 0 +991 1 1 1.5750000000000000e+00 -1.8014219144703780e+00 -1.5120102745243090e+01 9.1931438625465880e+00 0 1 0 +992 1 2 2.1000000000000001e+00 2.6258996467147959e+00 -1.3528044251547879e+01 6.4359209604334673e+00 0 1 0 +993 1 2 2.1000000000000001e+00 2.5462735712870828e+00 -1.6483086989741455e+01 6.4280448059299271e+00 0 1 0 +994 1 3 -1.0500000000000000e+00 2.7668677793957492e+00 -1.3599231581151475e+01 8.0541173845552336e+00 0 1 0 +995 1 3 -1.0500000000000000e+00 2.4115859888696161e+00 -1.6390097180934195e+01 8.0528587154913431e+00 0 1 0 +996 1 4 -9.4999999999999996e-01 -1.0775774466886645e-01 -1.5193886699232316e+01 8.1828630796662409e+00 0 1 0 +997 1 3 -1.0500000000000000e+00 1.2414435679215039e+00 -1.7185906236511268e+01 5.9541111590081126e+00 0 1 0 +998 1 3 -1.0500000000000000e+00 2.6583690581402628e+00 -1.5008709077371243e+01 5.9524182019502625e+00 0 1 0 +999 1 3 -1.0500000000000000e+00 3.8117604092858510e+00 -1.7334728765347329e+01 6.1439089845392907e+00 0 1 0 +1000 1 5 4.2499999999999999e-01 3.9913087790997537e-01 -1.4315031645600069e+01 8.0389424860193159e+00 0 1 0 +1001 1 1 1.5750000000000000e+00 5.9506242267994338e+00 -1.6623797722718635e+01 9.1936266671202027e+00 0 1 0 +1002 1 2 2.1000000000000001e+00 -1.0506484231044222e+01 -8.8863590027846140e+00 -6.4424197062906847e+00 1 1 1 +1003 1 2 2.1000000000000001e+00 -1.0483178876911868e+01 -1.4897205772908450e+01 -6.4344990737011551e+00 1 1 1 +1004 1 3 -1.0500000000000000e+00 9.9359983241624121e+00 -1.7781194811616796e+01 -8.0605324246202574e+00 0 1 1 +1005 1 3 -1.0500000000000000e+00 -1.0348454886651519e+01 -1.4989930517170308e+01 -8.0594191130608888e+00 1 1 1 +1006 1 4 -9.4999999999999996e-01 7.6507412164599700e+00 -1.6186429673609464e+01 -8.1893398094371470e+00 0 1 1 +1007 1 3 -1.0500000000000000e+00 6.3016333555911750e+00 -1.4194266019203811e+01 -5.9607817823241254e+00 0 1 1 +1008 1 3 -1.0500000000000000e+00 -1.0595502565248184e+01 -1.6371514961221607e+01 -5.9587127227690981e+00 1 1 1 +1009 1 3 -1.0500000000000000e+00 8.8913398738443519e+00 -1.4045424689210986e+01 -6.1504098107569085e+00 0 1 1 +1010 1 5 4.2499999999999999e-01 7.1438876889407545e+00 -1.7065178919134084e+01 -8.0455854917667171e+00 0 1 1 +1011 1 1 1.5750000000000000e+00 -1.2081215850500879e+01 -1.2140905395609227e+01 9.1936259420414075e+00 1 1 0 +1012 1 2 2.1000000000000001e+00 7.5253738692339525e+00 -1.3369269642659075e+01 -6.4424111597687768e+00 0 1 1 +1013 1 2 2.1000000000000001e+00 7.6049545385687836e+00 -1.0414276974615465e+01 -6.4344945980992394e+00 0 1 1 +1014 1 3 -1.0500000000000000e+00 7.3841902361699852e+00 -1.3298264178152394e+01 -8.0605659001293244e+00 0 1 1 +1015 1 3 -1.0500000000000000e+00 7.7396886594995777e+00 -1.0506995362793919e+01 -8.0594009666794690e+00 0 1 1 +1016 1 4 -9.4999999999999996e-01 -1.0381136033782756e+01 -1.1703557162467805e+01 -8.1893415275727754e+00 1 1 1 +1017 1 3 -1.0500000000000000e+00 8.9097683875275777e+00 -9.7113477429998554e+00 -5.9608036880169948e+00 0 1 1 +1018 1 3 -1.0500000000000000e+00 7.4926707750249442e+00 -1.1888611603990626e+01 -5.9587129622138315e+00 0 1 1 +1019 1 3 -1.0500000000000000e+00 6.3395050264705226e+00 -9.5625498048806605e+00 -6.1503917722438839e+00 0 1 1 +1020 1 5 4.2499999999999999e-01 9.7520894232513022e+00 -1.2582261952400280e+01 -8.0456251567187103e+00 0 1 1 +1021 1 1 1.5750000000000000e+00 5.9667370778486841e+00 -1.0637208378655330e+01 9.1931422048264544e+00 0 1 0 +1022 1 2 2.1000000000000001e+00 5.1777388423707791e+00 -1.8010972751178073e+01 6.4359121754500244e+00 0 1 0 +1023 1 2 2.1000000000000001e+00 5.1544257741572128e+00 -1.2000135136612140e+01 6.4280617964993638e+00 0 1 0 +1024 1 3 -1.0500000000000000e+00 5.3750375393141656e+00 -9.1162982390217753e+00 8.0541305365780431e+00 0 1 0 +1025 1 3 -1.0500000000000000e+00 5.0197352902290149e+00 -1.1907167532088971e+01 8.0528807818657455e+00 0 1 0 +1026 1 4 -9.4999999999999996e-01 -1.2979631380919937e+01 -1.0711006291129422e+01 8.1828700503208935e+00 1 1 0 +1027 1 3 -1.0500000000000000e+00 -1.1630417926343309e+01 -1.2702985659105673e+01 5.9540877407865125e+00 1 1 0 +1028 1 3 -1.0500000000000000e+00 5.2665416753772529e+00 -1.0525794189955786e+01 5.9524244742663583e+00 0 1 0 +1029 1 3 -1.0500000000000000e+00 6.4199440092225899e+00 -1.2851863874618857e+01 6.1439235679236717e+00 0 1 0 +1030 1 5 4.2499999999999999e-01 -1.2472661329901149e+01 -9.8320942016287756e+00 8.0389673105729180e+00 1 1 0 +1031 1 1 1.5750000000000000e+00 3.3585649047189889e+00 -1.5120093348845725e+01 9.1931411954480566e+00 0 1 0 +1032 1 2 2.1000000000000001e+00 -1.2854123594330217e+01 -1.3528045164039147e+01 6.4359116103016181e+00 1 1 0 +1033 1 2 2.1000000000000001e+00 -1.2933732590309141e+01 -1.6483074437729339e+01 6.4280564286910398e+00 1 1 0 +1034 1 3 -1.0500000000000000e+00 -1.2713145906083197e+01 -1.3599233632746742e+01 8.0541449495269859e+00 1 1 0 +1035 1 3 -1.0500000000000000e+00 -1.3068411221795856e+01 -1.6390092450304788e+01 8.0528554659863651e+00 1 1 0 +1036 1 4 -9.4999999999999996e-01 5.0522727200298299e+00 -1.5193845531977976e+01 8.1828789851171209e+00 0 1 0 +1037 1 3 -1.0500000000000000e+00 6.4014411247152445e+00 -1.7185907439712917e+01 5.9541046118211618e+00 0 1 0 +1038 1 3 -1.0500000000000000e+00 -1.2821635126045146e+01 -1.5008727883675213e+01 5.9524348860327301e+00 1 1 0 +1039 1 3 -1.0500000000000000e+00 -1.1668227901039566e+01 -1.7334733486964044e+01 6.1439059255523709e+00 1 1 0 +1040 1 5 4.2499999999999999e-01 5.5591473737227073e+00 -1.4315020006199346e+01 8.0390921650199161e+00 0 1 0 +1041 1 1 1.5750000000000000e+00 -9.5293899139307694e+00 -1.6623787874027308e+01 9.1936237921326978e+00 1 1 0 +1042 1 2 2.1000000000000001e+00 -5.3464608308947765e+00 -8.8863556911962096e+00 -6.4424092176216048e+00 1 1 1 +1043 1 2 2.1000000000000001e+00 -5.3231748952036835e+00 -1.4897218973116527e+01 -6.4345104241940962e+00 1 1 1 +1044 1 3 -1.0500000000000000e+00 -5.5439872108319319e+00 -1.7781192038243685e+01 -8.0605608257717840e+00 1 1 1 +1045 1 3 -1.0500000000000000e+00 -5.1884582357209057e+00 -1.4989934983843813e+01 -8.0594168014332030e+00 1 1 1 +1046 1 4 -9.4999999999999996e-01 -7.8292281421606535e+00 -1.6186388852721340e+01 -8.1893254252454835e+00 1 1 1 +1047 1 3 -1.0500000000000000e+00 -9.1783739996627851e+00 -1.4194270057895784e+01 -5.9607866851716160e+00 1 1 1 +1048 1 3 -1.0500000000000000e+00 -5.4354986326112078e+00 -1.6371500383854073e+01 -5.9587300155577916e+00 1 1 1 +1049 1 3 -1.0500000000000000e+00 -6.5886729673149071e+00 -1.4045419390766746e+01 -6.1504069109579946e+00 1 1 1 +1050 1 5 4.2499999999999999e-01 -8.3360989250281836e+00 -1.7065170615191157e+01 -8.0454468626928328e+00 1 1 1 +1051 1 1 1.5750000000000000e+00 -6.9212237057752120e+00 -1.2140905279613698e+01 9.1936281507656687e+00 1 1 0 +1052 1 2 2.1000000000000001e+00 -7.9546199637027923e+00 -1.3369283212241633e+01 -6.4424198458964543e+00 1 1 1 +1053 1 2 2.1000000000000001e+00 -7.8750220126689445e+00 -1.0414269957845629e+01 -6.4344945451348980e+00 1 1 1 +1054 1 3 -1.0500000000000000e+00 -8.0958159273297188e+00 -1.3298260211663301e+01 -8.0605513382597493e+00 1 1 1 +1055 1 3 -1.0500000000000000e+00 -7.7403088366973201e+00 -1.0507006356603398e+01 -8.0593941765754753e+00 1 1 1 +1056 1 4 -9.4999999999999996e-01 -5.2211297865863031e+00 -1.1703547420839435e+01 -8.1893607408242381e+00 1 1 1 +1057 1 3 -1.0500000000000000e+00 -6.5702769425775092e+00 -9.7113707796203723e+00 -5.9607925028876929e+00 1 1 1 +1058 1 3 -1.0500000000000000e+00 -7.9873270257999014e+00 -1.1888581912789562e+01 -5.9587188809513618e+00 1 1 1 +1059 1 3 -1.0500000000000000e+00 -9.1404883090905678e+00 -9.5625534027958778e+00 -6.1503936739305480e+00 1 1 1 +1060 1 5 4.2499999999999999e-01 -5.7279445458000602e+00 -1.2582296132873992e+01 -8.0457254720891491e+00 1 1 1 +1061 1 1 1.5750000000000000e+00 -9.5132712414377334e+00 -1.0637207901225382e+01 9.1931444515859475e+00 1 1 0 +1062 1 2 2.1000000000000001e+00 -1.0302264392719938e+01 -1.8010958511740707e+01 6.4359215057736137e+00 1 1 0 +1063 1 2 2.1000000000000001e+00 -1.0325597763836218e+01 -1.2000143885660425e+01 6.4280610801444311e+00 1 1 0 +1064 1 3 -1.0500000000000000e+00 -1.0104955208427846e+01 -9.1163013593801878e+00 8.0541136736620658e+00 1 1 0 +1065 1 3 -1.0500000000000000e+00 -1.0460267735536464e+01 -1.1907157783691902e+01 8.0528740633627187e+00 1 1 0 +1066 1 4 -9.4999999999999996e-01 -7.8196223206297599e+00 -1.0710993626792270e+01 8.1828507388406777e+00 1 1 0 +1067 1 3 -1.0500000000000000e+00 -6.4704642052545438e+00 -1.2703010171579383e+01 5.9540992478015298e+00 1 1 0 +1068 1 3 -1.0500000000000000e+00 -1.0213460429886737e+01 -1.0525822438026575e+01 5.9524290073249873e+00 1 1 0 +1069 1 3 -1.0500000000000000e+00 -9.0600631078363385e+00 -1.2851860507306093e+01 6.1439252136403280e+00 1 1 0 +1070 1 5 4.2499999999999999e-01 -7.3126955303015109e+00 -9.8321299462400891e+00 8.0388711780317124e+00 1 1 0 +1071 1 1 1.5750000000000000e+00 -1.2121421966983748e+01 -1.5120103097951539e+01 9.1931440500472021e+00 1 1 0 +1072 1 2 2.1000000000000001e+00 -7.6941002854421603e+00 -1.3528043511188180e+01 6.4359209951073471e+00 1 1 0 +1073 1 2 2.1000000000000001e+00 -7.7737266980076587e+00 -1.6483087090498845e+01 6.4280445509300250e+00 1 1 0 +1074 1 3 -1.0500000000000000e+00 -7.5531320715693777e+00 -1.3599231720429650e+01 8.0541168058333739e+00 1 1 0 +1075 1 3 -1.0500000000000000e+00 -7.9084140951184896e+00 -1.6390096710853786e+01 8.0528583515780205e+00 1 1 0 +1076 1 4 -9.4999999999999996e-01 -1.0427757546752302e+01 -1.5193886230508655e+01 8.1828631556698568e+00 1 1 0 +1077 1 3 -1.0500000000000000e+00 -9.0785565111582986e+00 -1.7185905911303450e+01 5.9541108650454166e+00 1 1 0 +1078 1 3 -1.0500000000000000e+00 -7.6616310609012928e+00 -1.5008709807568991e+01 5.9524186852294534e+00 1 1 0 +1079 1 3 -1.0500000000000000e+00 -6.5082396808725838e+00 -1.7334728922656321e+01 6.1439092326832387e+00 1 1 0 +1080 1 5 4.2499999999999999e-01 -9.9208689362280111e+00 -1.4315031144537746e+01 8.0389449231468681e+00 1 1 0 +1081 1 1 1.5750000000000000e+00 -4.3693757223617666e+00 -1.6623797501862640e+01 9.1936263177833482e+00 1 1 0 +1082 1 2 2.1000000000000001e+00 -1.8648460984142190e-01 -8.8863586813278168e+00 -6.4424195624530487e+00 1 1 1 +1083 1 2 2.1000000000000001e+00 -1.6317858587872180e-01 -1.4897205481208472e+01 -6.4344990010154151e+00 1 1 1 +1084 1 3 -1.0500000000000000e+00 -3.8400153394278114e-01 -1.7781193820588967e+01 -8.0605319542434177e+00 1 1 1 +1085 1 3 -1.0500000000000000e+00 -2.8454999893785526e-02 -1.4989931453633501e+01 -8.0594185181939455e+00 1 1 1 +1086 1 4 -9.4999999999999996e-01 -2.6692591084942503e+00 -1.6186430683271997e+01 -8.1893402866282834e+00 1 1 1 +1087 1 3 -1.0500000000000000e+00 -4.0183661906291688e+00 -1.4194265831610833e+01 -5.9607808745353807e+00 1 1 1 +1088 1 3 -1.0500000000000000e+00 -2.7550238935744531e-01 -1.6371514908008283e+01 -5.9587140310484852e+00 1 1 1 +1089 1 3 -1.0500000000000000e+00 -1.4286614237111728e+00 -1.4045424230641748e+01 -6.1504096183736543e+00 1 1 1 +1090 1 5 4.2499999999999999e-01 -3.1761126419061068e+00 -1.7065179317613428e+01 -8.0455892156983246e+00 1 1 1 +1091 1 1 1.5750000000000000e+00 -1.7612158961272968e+00 -1.2140905479144390e+01 9.1936260759968853e+00 1 1 0 +1092 1 2 2.1000000000000001e+00 -2.7946263215985852e+00 -1.3369269256921584e+01 -6.4424110744123801e+00 1 1 1 +1093 1 2 2.1000000000000001e+00 -2.7150458550199357e+00 -1.0414277514160078e+01 -6.4344944256095680e+00 1 1 1 +1094 1 3 -1.0500000000000000e+00 -2.9358094427693269e+00 -1.3298264285990225e+01 -8.0605669808735332e+00 1 1 1 +1095 1 3 -1.0500000000000000e+00 -2.5803112238951149e+00 -1.0506994842385364e+01 -8.0594011087445736e+00 1 1 1 +1096 1 4 -9.4999999999999996e-01 -6.1136511004701077e-02 -1.1703557808529808e+01 -8.1893413821177354e+00 1 1 1 +1097 1 3 -1.0500000000000000e+00 -1.4102319921708553e+00 -9.7113476086937851e+00 -5.9608039429212827e+00 1 1 1 +1098 1 3 -1.0500000000000000e+00 -2.8273291376600058e+00 -1.1888611910680980e+01 -5.9587126204693064e+00 1 1 1 +1099 1 3 -1.0500000000000000e+00 -3.9804942634357019e+00 -9.5625498131225903e+00 -6.1503916166810431e+00 1 1 1 +1100 1 5 4.2499999999999999e-01 -5.6791014020577890e-01 -1.2582261570234339e+01 -8.0456254549334609e+00 1 1 1 +1101 1 1 1.5750000000000000e+00 -4.3532626822440168e+00 -1.0637208536663195e+01 9.1931420264587729e+00 1 1 0 +1102 1 2 2.1000000000000001e+00 -5.1422605340029284e+00 -1.8010972814526962e+01 6.4359120870863116e+00 1 1 0 +1103 1 2 2.1000000000000001e+00 -5.1655741403261368e+00 -1.2000135207445506e+01 6.4280620600064111e+00 1 1 0 +1104 1 3 -1.0500000000000000e+00 -4.9449629476468537e+00 -9.1162979298605773e+00 8.0541307780712827e+00 1 1 0 +1105 1 3 -1.0500000000000000e+00 -5.3002653908317328e+00 -1.1907167772463211e+01 8.0528808659252675e+00 1 1 0 +1106 1 4 -9.4999999999999996e-01 -2.6596311317213690e+00 -1.0711006131470690e+01 8.1828701429922646e+00 1 1 0 +1107 1 3 -1.0500000000000000e+00 -1.3104180489574517e+00 -1.2702985515202105e+01 5.9540876691461300e+00 1 1 0 +1108 1 3 -1.0500000000000000e+00 -5.0534589320363521e+00 -1.0525793717166195e+01 5.9524239638193972e+00 1 1 0 +1109 1 3 -1.0500000000000000e+00 -3.9000552799467680e+00 -1.2851864283020131e+01 6.1439229758272287e+00 1 1 0 +1110 1 5 4.2499999999999999e-01 -2.1526612288429927e+00 -9.8320937887400692e+00 8.0389686940673108e+00 1 1 0 +1111 1 1 1.5750000000000000e+00 -6.9614351741271125e+00 -1.5120093227433923e+01 9.1931413794662760e+00 1 1 0 +1112 1 2 2.1000000000000001e+00 -2.5341240788726989e+00 -1.3528045681933817e+01 6.4359119500026907e+00 1 1 0 +1113 1 2 2.1000000000000001e+00 -2.6137328955640973e+00 -1.6483073671230674e+01 6.4280561366629687e+00 1 1 0 +1114 1 3 -1.0500000000000000e+00 -2.3931455622464295e+00 -1.3599233318386894e+01 8.0541451348176771e+00 1 1 0 +1115 1 3 -1.0500000000000000e+00 -2.7484109330614652e+00 -1.6390092942449684e+01 8.0528560015686210e+00 1 1 0 +1116 1 4 -9.4999999999999996e-01 -5.2677274043188298e+00 -1.5193844862391190e+01 8.1828790257998492e+00 1 1 0 +1117 1 3 -1.0500000000000000e+00 -3.9185585465782733e+00 -1.7185907339500744e+01 5.9541042049943371e+00 1 1 0 +1118 1 3 -1.0500000000000000e+00 -2.5016349383751777e+00 -1.5008727970228067e+01 5.9524344787992991e+00 1 1 0 +1119 1 3 -1.0500000000000000e+00 -1.3482285748874521e+00 -1.7334733258778282e+01 6.1439062228621797e+00 1 1 0 +1120 1 5 4.2499999999999999e-01 -4.7608525391156977e+00 -1.4315020002600260e+01 8.0390931457615267e+00 1 1 0 +1121 1 1 1.5750000000000000e+00 8.4695165366353464e-01 -7.6579835812050305e+00 9.1936288874475025e+00 0 1 0 +1122 1 2 2.1000000000000001e+00 5.0298854047814761e+00 7.9466019669347077e-02 -6.4424144556152356e+00 0 1 1 +1123 1 2 2.1000000000000001e+00 5.0531536696119623e+00 -5.9314030709104628e+00 -6.4345137045491718e+00 0 1 1 +1124 1 3 -1.0500000000000000e+00 4.8323591387051597e+00 -8.8153742682486840e+00 -8.0605820239111772e+00 0 1 1 +1125 1 3 -1.0500000000000000e+00 5.1878732372825311e+00 -6.0241061595734156e+00 -8.0594120212256826e+00 0 1 1 +1126 1 4 -9.4999999999999996e-01 2.5470666548004353e+00 -7.2206258319811312e+00 -8.1893702843091258e+00 0 1 1 +1127 1 3 -1.0500000000000000e+00 1.1979474982824225e+00 -5.2284455720511929e+00 -5.9607876425440542e+00 0 1 1 +1128 1 3 -1.0500000000000000e+00 4.9408304873956261e+00 -7.4056780595905938e+00 -5.9586989539517790e+00 0 1 1 +1129 1 3 -1.0500000000000000e+00 3.7876635127476206e+00 -5.0795967839315637e+00 -6.1504077701680906e+00 0 1 1 +1130 1 5 4.2499999999999999e-01 2.0402139399280124e+00 -8.0994421271782215e+00 -8.0457925512527595e+00 0 1 1 +1131 1 1 1.5750000000000000e+00 3.4551102318040119e+00 -3.1750602373809240e+00 9.1936249963033703e+00 0 1 0 +1132 1 2 2.1000000000000001e+00 2.4217092647353429e+00 -4.4034682343922888e+00 -6.4424100556567545e+00 0 1 1 +1133 1 2 2.1000000000000001e+00 2.5013293209638849e+00 -1.4484603202585618e+00 -6.4344992392404317e+00 0 1 1 +1134 1 3 -1.0500000000000000e+00 2.2805060226959757e+00 -4.3324466752627728e+00 -8.0605363775723244e+00 0 1 1 +1135 1 3 -1.0500000000000000e+00 2.6360394328354282e+00 -1.5411974066626648e+00 -8.0594077778299429e+00 0 1 1 +1136 1 4 -9.4999999999999996e-01 5.1552544755530079e+00 -2.7376679909019241e+00 -8.1893317299450903e+00 0 1 1 +1137 1 3 -1.0500000000000000e+00 3.8060930080128710e+00 -7.4554775156575559e-01 -5.9607837224071307e+00 0 1 1 +1138 1 3 -1.0500000000000000e+00 2.3890075299204767e+00 -2.9227581668061351e+00 -5.9587353346909673e+00 0 1 1 +1139 1 3 -1.0500000000000000e+00 1.2358408994011736e+00 -5.9670616076288141e-01 -6.1504018482632379e+00 0 1 1 +1140 1 5 4.2499999999999999e-01 4.6483926264102795e+00 -3.6164252934885788e+00 -8.0454920049899243e+00 0 1 1 +1141 1 1 1.5750000000000000e+00 8.6307055672640232e-01 -1.6713754640994978e+00 9.1931460949904640e+00 0 1 0 +1142 1 2 2.1000000000000001e+00 7.4067440539106855e-02 -9.0451227689768317e+00 6.4359123217975327e+00 0 1 0 +1143 1 2 2.1000000000000001e+00 5.0752316497217009e-02 -3.0343466932277092e+00 6.4280512560994687e+00 0 1 0 +1144 1 3 -1.0500000000000000e+00 2.7137419103710414e-01 -1.5049744182525160e-01 8.0541123492163607e+00 0 1 0 +1145 1 3 -1.0500000000000000e+00 -8.3917914878398392e-02 -2.9413479949048895e+00 8.0528600947866131e+00 0 1 0 +1146 1 4 -9.4999999999999996e-01 2.5567365503950334e+00 -1.7451597138855846e+00 8.1828414199204254e+00 0 1 0 +1147 1 3 -1.0500000000000000e+00 3.9059034396848951e+00 -3.7371848336857560e+00 5.9541096293006248e+00 0 1 0 +1148 1 3 -1.0500000000000000e+00 1.6286724521224549e-01 -1.5599986393757455e+00 5.9524414687461746e+00 0 1 0 +1149 1 3 -1.0500000000000000e+00 1.3162680069554646e+00 -3.8860046896279545e+00 6.1439117370450713e+00 0 1 0 +1150 1 5 4.2499999999999999e-01 3.0636187093141718e+00 -8.6634582863043264e-01 8.0388105803397210e+00 0 1 0 +1151 1 1 1.5750000000000000e+00 -1.7450965412416704e+00 -6.1542721885858267e+00 9.1931396400753584e+00 0 1 0 +1152 1 2 2.1000000000000001e+00 2.6822454390238182e+00 -4.5622313652435196e+00 6.4359253215799903e+00 0 1 0 +1153 1 2 2.1000000000000001e+00 2.6026017072422256e+00 -7.5172435230657051e+00 6.4280525353786011e+00 0 1 0 +1154 1 3 -1.0500000000000000e+00 2.8231982980173314e+00 -4.6333936871729211e+00 8.0541324435706265e+00 0 1 0 +1155 1 3 -1.0500000000000000e+00 2.4679139242312864e+00 -7.4242702203153303e+00 8.0528635321919779e+00 0 1 0 +1156 1 4 -9.4999999999999996e-01 -5.1408619376051234e-02 -6.2280255545507099e+00 8.1829007040250481e+00 0 1 0 +1157 1 3 -1.0500000000000000e+00 1.2977674624764681e+00 -8.2200857847518538e+00 5.9541052800705856e+00 0 1 0 +1158 1 3 -1.0500000000000000e+00 2.7147125497670821e+00 -6.0428853524192228e+00 5.9523886568029081e+00 0 1 0 +1159 1 3 -1.0500000000000000e+00 3.8680955259932048e+00 -8.3689256292345569e+00 6.1439186514543209e+00 0 1 0 +1160 1 5 4.2499999999999999e-01 4.5549352909885421e-01 -5.3491180364217001e+00 8.0392291387924644e+00 0 1 0 +1161 1 1 1.5750000000000000e+00 6.0069661936035175e+00 -7.6579937548320185e+00 9.1936316044666739e+00 0 1 0 +1162 1 2 2.1000000000000001e+00 -1.0450137639744804e+01 7.9463299035463564e-02 -6.4424243710353402e+00 1 1 1 +1163 1 2 2.1000000000000001e+00 -1.0426849451533693e+01 -5.9313896376259745e+00 -6.4345018460644283e+00 1 1 1 +1164 1 3 -1.0500000000000000e+00 9.9923438028197751e+00 -8.8153761390063448e+00 -8.0605530520838684e+00 0 1 1 +1165 1 3 -1.0500000000000000e+00 -1.0292123773060068e+01 -6.0241018369519264e+00 -8.0594139253470427e+00 1 1 1 +1166 1 4 -9.4999999999999996e-01 7.7070346980525173e+00 -7.2206693221354694e+00 -8.1893857246142900e+00 0 1 1 +1167 1 3 -1.0500000000000000e+00 6.3579542845899226e+00 -5.2284417436908193e+00 -5.9607824168769161e+00 0 1 1 +1168 1 3 -1.0500000000000000e+00 -1.0539173651568435e+01 -7.4056923085044541e+00 -5.9586827688544748e+00 1 1 1 +1169 1 3 -1.0500000000000000e+00 8.9476763873501461e+00 -5.0796014856025877e+00 -6.1504115174662424e+00 0 1 1 +1170 1 5 4.2499999999999999e-01 7.2001993237605930e+00 -8.0994521615003521e+00 -8.0459408726587203e+00 0 1 1 +1171 1 1 1.5750000000000000e+00 -1.2024881927933214e+01 -3.1750599741083469e+00 9.1936226503397407e+00 1 1 0 +1172 1 2 2.1000000000000001e+00 7.5817028306539775e+00 -4.4034548242472553e+00 -6.4424012953316998e+00 0 1 1 +1173 1 2 2.1000000000000001e+00 7.6613050161260396e+00 -1.4484663840709260e+00 -6.4344990879805639e+00 0 1 1 +1174 1 3 -1.0500000000000000e+00 7.4405122110527309e+00 -4.3324502105469040e+00 -8.0605503307031601e+00 0 1 1 +1175 1 3 -1.0500000000000000e+00 7.7960372596729002e+00 -1.5411873078722387e+00 -8.0594145656169474e+00 0 1 1 +1176 1 4 -9.4999999999999996e-01 -1.0324751332420679e+01 -2.7376760680379526e+00 -8.1893113790367398e+00 1 1 1 +1177 1 3 -1.0500000000000000e+00 8.9661392654718526e+00 -7.4552372525409538e-01 -5.9607953656302595e+00 0 1 1 +1178 1 3 -1.0500000000000000e+00 7.5490052861507984e+00 -2.9227882817179367e+00 -5.9587292162986722e+00 0 1 1 +1179 1 3 -1.0500000000000000e+00 6.3958341876680791e+00 -5.9670249615731663e-01 -6.1504001903853247e+00 0 1 1 +1180 1 5 4.2499999999999999e-01 9.8084275444973414e+00 -3.6163895221434412e+00 -8.0453831689662785e+00 0 1 1 +1181 1 1 1.5750000000000000e+00 6.0230793220357306e+00 -1.6713760727027740e+00 9.1931436640286570e+00 0 1 0 +1182 1 2 2.1000000000000001e+00 5.2340703084782234e+00 -9.0451373900601055e+00 6.4359026509421398e+00 0 1 0 +1183 1 2 2.1000000000000001e+00 5.2107768285475249e+00 -3.0343378220597543e+00 6.4280520030326400e+00 0 1 0 +1184 1 3 -1.0500000000000000e+00 5.4313667981565832e+00 -1.5049347755671505e-01 8.0541295280698009e+00 0 1 0 +1185 1 3 -1.0500000000000000e+00 5.0760850477762016e+00 -2.9413590110961252e+00 8.0528672520399454e+00 0 1 0 +1186 1 4 -9.4999999999999996e-01 -1.2923273102973829e+01 -1.7451732121810899e+00 8.1828599921332490e+00 1 1 0 +1187 1 3 -1.0500000000000000e+00 -1.1574049043750753e+01 -3.7371601802106404e+00 5.9540991225733642e+00 1 1 0 +1188 1 3 -1.0500000000000000e+00 5.3228691356732281e+00 -1.5599701988768047e+00 5.9524365669383243e+00 0 1 0 +1189 1 3 -1.0500000000000000e+00 6.4762747623866446e+00 -3.8860082222617720e+00 6.1439098279782520e+00 0 1 0 +1190 1 5 4.2499999999999999e-01 -1.2416347906588287e+01 -8.6631108188533545e-01 8.0389014904005194e+00 1 1 0 +1191 1 1 1.5750000000000000e+00 3.4148894200107200e+00 -6.1542622930241908e+00 9.1931366055821719e+00 0 1 0 +1192 1 2 2.1000000000000001e+00 -1.2797778702965626e+01 -4.5622320761539967e+00 6.4359157700181306e+00 1 1 0 +1193 1 2 2.1000000000000001e+00 -1.2877404237061196e+01 -7.5172309934459047e+00 6.4280643167095981e+00 1 1 0 +1194 1 3 -1.0500000000000000e+00 -1.2656816171316713e+01 -4.6333960070141416e+00 8.0541603707338680e+00 1 1 0 +1195 1 3 -1.0500000000000000e+00 -1.3012083101506889e+01 -7.4242649986939213e+00 8.0528602947442778e+00 1 1 0 +1196 1 4 -9.4999999999999996e-01 5.1086228485452754e+00 -6.2279825781387714e+00 8.1829178979826871e+00 0 1 0 +1197 1 3 -1.0500000000000000e+00 6.4577656205449188e+00 -8.2200870263303347e+00 5.9540987494082156e+00 0 1 0 +1198 1 3 -1.0500000000000000e+00 -1.2765291524992206e+01 -6.0429045661158707e+00 5.9524054565834668e+00 1 1 0 +1199 1 3 -1.0500000000000000e+00 -1.1611893334617134e+01 -8.3689294997385222e+00 6.1439150437810142e+00 1 1 0 +1200 1 5 4.2499999999999999e-01 5.6155110306614677e+00 -5.3491040803435190e+00 8.0393878066564533e+00 0 1 0 +1201 1 1 1.5750000000000000e+00 -9.4730482558538363e+00 -7.6579837804608353e+00 9.1936288584421817e+00 1 1 0 +1202 1 2 2.1000000000000001e+00 -5.2901137812505343e+00 7.9465578875971943e-02 -6.4424141224911704e+00 1 1 1 +1203 1 2 2.1000000000000001e+00 -5.2668457657427714e+00 -5.9314030152575619e+00 -6.4345136025435696e+00 1 1 1 +1204 1 3 -1.0500000000000000e+00 -5.4876411141658021e+00 -8.8153737446390359e+00 -8.0605818622866803e+00 1 1 1 +1205 1 3 -1.0500000000000000e+00 -5.1321272527986546e+00 -6.0241062466034769e+00 -8.0594120618712797e+00 1 1 1 +1206 1 4 -9.4999999999999996e-01 -7.7729334170461382e+00 -7.2206262093781639e+00 -8.1893704172959332e+00 1 1 1 +1207 1 3 -1.0500000000000000e+00 -9.1220532114999084e+00 -5.2284458130184035e+00 -5.9607879501683279e+00 1 1 1 +1208 1 3 -1.0500000000000000e+00 -5.3791700396304432e+00 -7.4056785499597986e+00 -5.9586994192034970e+00 1 1 1 +1209 1 3 -1.0500000000000000e+00 -6.5323364101775097e+00 -5.0795968883872256e+00 -6.1504080690006111e+00 1 1 1 +1210 1 5 4.2499999999999999e-01 -8.2797860458884607e+00 -8.0994421096420997e+00 -8.0457936049874998e+00 1 1 1 +1211 1 1 1.5750000000000000e+00 -6.8648895692884251e+00 -3.1750601185026568e+00 9.1936250796126728e+00 1 1 0 +1212 1 2 2.1000000000000001e+00 -7.8982904263320277e+00 -4.4034684490191758e+00 -6.4424103941693547e+00 1 1 1 +1213 1 2 2.1000000000000001e+00 -7.8186708591875442e+00 -1.4484597541953050e+00 -6.4344993359968523e+00 1 1 1 +1214 1 3 -1.0500000000000000e+00 -8.0394941486076519e+00 -4.3324466787230307e+00 -8.0605359249190123e+00 1 1 1 +1215 1 3 -1.0500000000000000e+00 -7.6839605876128365e+00 -1.5411977245256949e+00 -8.0594077717620856e+00 1 1 1 +1216 1 4 -9.4999999999999996e-01 -5.1647454040881282e+00 -2.7376674564410823e+00 -8.1893315607054049e+00 1 1 1 +1217 1 3 -1.0500000000000000e+00 -6.5139066907486161e+00 -7.4554731891745618e-01 -5.9607837703642241e+00 1 1 1 +1218 1 3 -1.0500000000000000e+00 -7.9309926183745523e+00 -2.9227576840502572e+00 -5.9587353580265621e+00 1 1 1 +1219 1 3 -1.0500000000000000e+00 -9.0841593543895360e+00 -5.9670620551901621e-01 -6.1504020768312335e+00 1 1 1 +1220 1 5 4.2499999999999999e-01 -5.6716072349666886e+00 -3.6164251093405397e+00 -8.0454906260480783e+00 1 1 1 +1221 1 1 1.5750000000000000e+00 -9.4569292783711720e+00 -1.6713754920263852e+00 9.1931457295587080e+00 1 1 0 +1222 1 2 2.1000000000000001e+00 -1.0245932376290614e+01 -9.0451235386775792e+00 6.4359124866582462e+00 1 1 0 +1223 1 2 2.1000000000000001e+00 -1.0269246952870757e+01 -3.0343462448060272e+00 6.4280513194600832e+00 1 1 0 +1224 1 3 -1.0500000000000000e+00 -1.0048625782907161e+01 -1.5049666929490613e-01 8.0541125763199020e+00 1 1 0 +1225 1 3 -1.0500000000000000e+00 -1.0403918287278653e+01 -2.9413486509055247e+00 8.0528602350875680e+00 1 1 0 +1226 1 4 -9.4999999999999996e-01 -7.7632636474169150e+00 -1.7451601758199367e+00 8.1828410557435127e+00 1 1 0 +1227 1 3 -1.0500000000000000e+00 -6.4140961797655454e+00 -3.7371846807874363e+00 5.9541096999475336e+00 1 1 0 +1228 1 3 -1.0500000000000000e+00 -1.0157133031150034e+01 -1.5599995082696054e+00 5.9524404810865761e+00 1 1 0 +1229 1 3 -1.0500000000000000e+00 -9.0037325780420030e+00 -3.8860049270011618e+00 6.1439117463650170e+00 1 1 0 +1230 1 5 4.2499999999999999e-01 -7.2563815502586255e+00 -8.6634628906294964e-01 8.0388078115699031e+00 1 1 0 +1231 1 1 1.5750000000000000e+00 -1.2065096650972574e+01 -6.1542722772754583e+00 9.1931397726777710e+00 1 1 0 +1232 1 2 2.1000000000000001e+00 -7.6377546012995223e+00 -4.5622303585522523e+00 6.4359252178928603e+00 1 1 0 +1233 1 2 2.1000000000000001e+00 -7.7173985866608206e+00 -7.5172441124993092e+00 6.4280522853100841e+00 1 1 0 +1234 1 3 -1.0500000000000000e+00 -7.4968018474351847e+00 -4.6333944697759453e+00 8.0541317707799216e+00 1 1 0 +1235 1 3 -1.0500000000000000e+00 -7.8520862052053939e+00 -7.4242695437274406e+00 8.0528631393504213e+00 1 1 0 +1236 1 4 -9.4999999999999996e-01 -1.0371408885631821e+01 -6.2280260117520783e+00 8.1829008047331513e+00 1 1 0 +1237 1 3 -1.0500000000000000e+00 -9.0222328910023926e+00 -8.2200853313923243e+00 5.9541052342574226e+00 1 1 0 +1238 1 3 -1.0500000000000000e+00 -7.6052877106027434e+00 -6.0428855091388112e+00 5.9523894388192833e+00 1 1 0 +1239 1 3 -1.0500000000000000e+00 -6.4519043738629689e+00 -8.3689258339210468e+00 6.1439186596132167e+00 1 1 0 +1240 1 5 4.2499999999999999e-01 -9.8645060505972708e+00 -5.3491171533452899e+00 8.0392299847806328e+00 1 1 0 +1241 1 1 1.5750000000000000e+00 -4.3130335719799664e+00 -7.6579937038842196e+00 9.1936314019332954e+00 1 1 0 +1242 1 2 2.1000000000000001e+00 -1.3013744627974866e-01 7.9462913475630614e-02 -6.4424246376464893e+00 1 1 1 +1243 1 2 2.1000000000000001e+00 -1.0684893537057505e-01 -5.9313893508898428e+00 -6.4345017895585537e+00 1 1 1 +1244 1 3 -1.0500000000000000e+00 -3.2765635106517799e-01 -8.8153758391408683e+00 -8.0605526742101183e+00 1 1 1 +1245 1 3 -1.0500000000000000e+00 2.7875841094589404e-02 -6.0241024867204338e+00 -8.0594144214765731e+00 1 1 1 +1246 1 4 -9.4999999999999996e-01 -2.6129651405688552e+00 -7.2206691446852744e+00 -8.1893860636445819e+00 1 1 1 +1247 1 3 -1.0500000000000000e+00 -3.9620450314031350e+00 -5.2284410824498675e+00 -5.9607825544872162e+00 1 1 1 +1248 1 3 -1.0500000000000000e+00 -2.1917390278932380e-01 -7.4056927498705267e+00 -5.9586833079493466e+00 1 1 1 +1249 1 3 -1.0500000000000000e+00 -1.3723243147179893e+00 -5.0796017338512662e+00 -6.1504112915507374e+00 1 1 1 +1250 1 5 4.2499999999999999e-01 -3.1198011720613454e+00 -8.0994528008667253e+00 -8.0459422208187643e+00 1 1 1 +1251 1 1 1.5750000000000000e+00 -1.7048821048822589e+00 -3.1750600233974851e+00 9.1936227443404306e+00 1 1 0 +1252 1 2 2.1000000000000001e+00 -2.7382971234679294e+00 -4.4034543566522828e+00 -6.4424013859544047e+00 1 1 1 +1253 1 2 2.1000000000000001e+00 -2.6586950753550083e+00 -1.4484668500258664e+00 -6.4344993053995712e+00 1 1 1 +1254 1 3 -1.0500000000000000e+00 -2.8794880275479802e+00 -4.3324506611342049e+00 -8.0605508713604959e+00 1 1 1 +1255 1 3 -1.0500000000000000e+00 -2.5239630752470426e+00 -1.5411866297456065e+00 -8.0594147792074153e+00 1 1 1 +1256 1 4 -9.4999999999999996e-01 -4.7517837259558604e-03 -2.7376768429853673e+00 -8.1893112828875445e+00 1 1 1 +1257 1 3 -1.0500000000000000e+00 -1.3538609137908306e+00 -7.4552332505261631e-01 -5.9607953412511501e+00 1 1 1 +1258 1 3 -1.0500000000000000e+00 -2.7709951342120993e+00 -2.9227884148814525e+00 -5.9587287907420370e+00 1 1 1 +1259 1 3 -1.0500000000000000e+00 -3.9241656194851835e+00 -5.9670276827438684e-01 -6.1504002860173532e+00 1 1 1 +1260 1 5 4.2499999999999999e-01 -5.1157204379419063e-01 -3.6163887288381531e+00 -8.0453830198534977e+00 1 1 1 +1261 1 1 1.5750000000000000e+00 -4.2969203280827042e+00 -1.6713763688959737e+00 9.1931435527350907e+00 1 1 0 +1262 1 2 2.1000000000000001e+00 -5.0859285809060815e+00 -9.0451378610562490e+00 6.4359028036352743e+00 1 1 0 +1263 1 2 2.1000000000000001e+00 -5.1092223160746624e+00 -3.0343377842534469e+00 6.4280523464977879e+00 1 1 0 +1264 1 3 -1.0500000000000000e+00 -4.8886336868453881e+00 -1.5049298815613810e-01 8.0541300922261030e+00 1 1 0 +1265 1 3 -1.0500000000000000e+00 -5.2439155117684226e+00 -2.9413591861830017e+00 8.0528672575652891e+00 1 1 0 +1266 1 4 -9.4999999999999996e-01 -2.6032732264105301e+00 -1.7451740386941132e+00 8.1828598914546760e+00 1 1 0 +1267 1 3 -1.0500000000000000e+00 -1.2540490739490959e+00 -3.7371600128887970e+00 5.9540989905604338e+00 1 1 0 +1268 1 3 -1.0500000000000000e+00 -4.9971316149433278e+00 -1.5599701828983008e+00 5.9524360634314295e+00 1 1 0 +1269 1 3 -1.0500000000000000e+00 -3.8437253850415853e+00 -3.8860083322717820e+00 6.1439094566028505e+00 1 1 0 +1270 1 5 4.2499999999999999e-01 -2.0963478358362906e+00 -8.6631093607094911e-01 8.0388999212996310e+00 1 1 0 +1271 1 1 1.5750000000000000e+00 -6.9051103097426907e+00 -6.1542621657147709e+00 9.1931367563616888e+00 1 1 0 +1272 1 2 2.1000000000000001e+00 -2.4777787674654199e+00 -4.5622327426858931e+00 6.4359160209892181e+00 1 1 0 +1273 1 2 2.1000000000000001e+00 -2.5574043892191067e+00 -7.5172298950838190e+00 6.4280642763354940e+00 1 1 0 +1274 1 3 -1.0500000000000000e+00 -2.3368161191143999e+00 -4.6333959836381862e+00 8.0541606972964814e+00 1 1 0 +1275 1 3 -1.0500000000000000e+00 -2.6920831091204462e+00 -7.4242654010828897e+00 8.0528604112015607e+00 1 1 0 +1276 1 4 -9.4999999999999996e-01 -5.2113770815501210e+00 -6.2279820619212582e+00 8.1829178539255096e+00 1 1 0 +1277 1 3 -1.0500000000000000e+00 -3.8622341308639339e+00 -8.2200867295059776e+00 5.9540986555569546e+00 1 1 0 +1278 1 3 -1.0500000000000000e+00 -2.4452916356073002e+00 -6.0429049672168205e+00 5.9524054018626558e+00 1 1 0 +1279 1 3 -1.0500000000000000e+00 -1.2918938182515838e+00 -8.3689297483017420e+00 6.1439149539106701e+00 1 1 0 +1280 1 5 4.2499999999999999e-01 -4.7044890687991749e+00 -5.3491044489278803e+00 8.0393882099475782e+00 1 1 0 Velocities 1 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 2 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 3 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 4 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 5 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 6 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 7 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 8 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 9 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 10 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 11 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 12 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 13 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 14 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 15 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 16 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 17 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 18 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 19 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 20 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 21 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 22 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 23 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 24 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 25 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 26 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 27 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 28 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 29 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 30 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 31 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 32 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 33 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 34 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 35 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 36 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 37 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 38 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 39 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 40 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 41 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 42 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 43 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 44 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 45 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 46 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 47 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 48 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 49 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 50 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 51 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 52 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 53 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 54 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 55 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 56 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 57 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 58 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 59 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 60 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 61 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 62 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 63 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 64 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 65 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 66 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 67 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 68 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 69 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 70 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 71 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 72 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 73 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 74 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 75 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 76 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 77 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 78 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 79 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 80 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 81 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 82 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 83 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 84 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 85 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 86 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 87 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 88 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 89 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 90 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 91 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 92 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 93 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 94 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 95 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 96 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 97 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 98 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 99 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 100 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 101 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 102 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 103 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 104 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 105 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 106 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 107 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 108 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 109 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 110 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 111 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 112 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 113 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 114 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 115 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 116 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 117 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 118 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 119 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 120 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 121 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 122 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 123 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 124 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 125 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 126 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 127 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 128 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 129 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 130 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 131 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 132 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 133 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 134 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 135 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 136 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 137 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 138 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 139 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 140 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 141 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 142 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 143 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 144 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 145 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 146 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 147 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 148 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 149 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 150 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 151 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 152 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 153 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 154 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 155 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 156 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 157 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 158 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 159 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 160 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 161 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 162 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 163 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 164 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 165 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 166 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 167 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 168 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 169 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 170 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 171 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 172 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 173 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 174 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 175 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 176 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 177 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 178 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 179 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 180 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 181 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 182 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 183 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 184 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 185 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 186 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 187 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 188 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 189 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 190 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 191 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 192 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 193 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 194 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 195 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 196 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 197 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 198 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 199 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 200 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 201 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 202 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 203 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 204 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 205 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 206 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 207 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 208 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 209 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 210 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 211 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 212 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 213 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 214 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 215 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 216 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 217 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 218 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 219 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 220 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 221 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 222 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 223 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 224 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 225 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 226 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 227 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 228 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 229 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 230 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 231 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 232 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 233 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 234 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 235 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 236 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 237 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 238 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 239 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 240 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 241 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 242 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 243 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 244 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 245 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 246 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 247 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 248 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 249 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 250 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 251 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 252 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 253 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 254 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 255 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 256 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 257 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 258 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 259 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 260 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 261 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 262 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 263 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 264 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 265 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 266 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 267 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 268 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 269 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 270 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 271 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 272 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 273 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 274 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 275 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 276 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 277 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 278 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 279 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 280 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 281 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 282 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 283 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 284 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 285 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 286 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 287 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 288 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 289 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 290 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 291 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 292 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 293 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 294 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 295 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 296 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 297 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 298 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 299 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 300 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 301 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 302 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 303 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 304 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 305 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 306 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 307 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 308 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 309 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 310 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 311 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 312 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 313 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 314 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 315 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 316 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 317 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 318 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 319 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 320 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 321 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 322 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 323 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 324 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 325 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 326 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 327 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 328 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 329 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 330 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 331 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 332 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 333 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 334 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 335 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 336 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 337 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 338 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 339 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 340 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 341 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 342 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 343 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 344 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 345 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 346 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 347 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 348 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 349 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 350 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 351 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 352 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 353 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 354 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 355 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 356 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 357 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 358 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 359 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 360 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 361 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 362 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 363 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 364 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 365 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 366 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 367 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 368 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 369 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 370 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 371 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 372 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 373 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 374 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 375 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 376 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 377 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 378 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 379 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 380 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 381 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 382 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 383 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 384 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 385 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 386 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 387 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 388 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 389 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 390 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 391 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 392 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 393 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 394 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 395 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 396 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 397 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 398 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 399 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 400 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 401 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 402 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 403 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 404 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 405 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 406 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 407 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 408 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 409 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 410 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 411 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 412 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 413 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 414 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 415 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 416 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 417 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 418 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 419 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 420 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 421 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 422 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 423 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 424 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 425 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 426 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 427 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 428 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 429 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 430 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 431 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 432 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 433 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 434 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 435 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 436 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 437 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 438 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 439 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 440 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 441 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 442 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 443 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 444 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 445 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 446 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 447 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 448 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 449 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 450 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 451 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 452 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 453 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 454 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 455 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 456 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 457 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 458 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 459 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 460 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 461 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 462 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 463 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 464 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 465 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 466 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 467 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 468 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 469 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 470 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 471 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 472 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 473 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 474 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 475 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 476 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 477 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 478 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 479 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 480 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 481 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 482 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 483 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 484 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 485 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 486 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 487 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 488 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 489 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 490 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 491 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 492 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 493 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 494 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 495 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 496 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 497 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 498 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 499 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 500 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 501 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 502 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 503 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 504 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 505 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 506 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 507 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 508 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 509 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 510 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 511 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 512 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 513 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 514 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 515 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 516 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 517 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 518 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 519 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 520 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 521 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 522 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 523 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 524 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 525 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 526 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 527 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 528 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 529 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 530 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 531 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 532 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 533 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 534 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 535 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 536 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 537 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 538 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 539 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 540 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 541 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 542 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 543 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 544 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 545 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 546 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 547 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 548 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 549 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 550 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 551 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 552 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 553 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 554 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 555 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 556 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 557 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 558 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 559 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 560 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 561 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 562 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 563 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 564 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 565 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 566 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 567 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 568 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 569 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 570 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 571 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 572 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 573 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 574 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 575 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 576 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 577 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 578 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 579 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 580 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 581 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 582 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 583 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 584 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 585 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 586 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 587 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 588 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 589 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 590 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 591 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 592 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 593 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 594 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 595 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 596 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 597 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 598 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 599 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 600 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 601 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 602 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 603 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 604 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 605 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 606 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 607 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 608 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 609 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 610 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 611 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 612 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 613 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 614 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 615 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 616 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 617 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 618 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 619 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 620 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 621 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 622 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 623 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 624 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 625 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 626 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 627 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 628 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 629 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 630 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 631 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 632 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 633 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 634 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 635 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 636 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 637 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 638 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 639 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 640 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 641 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 642 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 643 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 644 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 645 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 646 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 647 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 648 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 649 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 650 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 651 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 652 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 653 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 654 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 655 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 656 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 657 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 658 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 659 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 660 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 661 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 662 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 663 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 664 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 665 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 666 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 667 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 668 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 669 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 670 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 671 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 672 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 673 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 674 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 675 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 676 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 677 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 678 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 679 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 680 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 681 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 682 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 683 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 684 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 685 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 686 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 687 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 688 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 689 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 690 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 691 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 692 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 693 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 694 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 695 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 696 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 697 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 698 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 699 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 700 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 701 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 702 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 703 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 704 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 705 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 706 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 707 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 708 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 709 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 710 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 711 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 712 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 713 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 714 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 715 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 716 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 717 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 718 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 719 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 720 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 721 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 722 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 723 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 724 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 725 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 726 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 727 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 728 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 729 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 730 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 731 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 732 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 733 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 734 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 735 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 736 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 737 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 738 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 739 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 740 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 741 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 742 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 743 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 744 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 745 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 746 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 747 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 748 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 749 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 750 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 751 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 752 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 753 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 754 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 755 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 756 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 757 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 758 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 759 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 760 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 761 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 762 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 763 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 764 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 765 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 766 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 767 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 768 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 769 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 770 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 771 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 772 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 773 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 774 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 775 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 776 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 777 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 778 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 779 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 780 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 781 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 782 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 783 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 784 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 785 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 786 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 787 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 788 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 789 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 790 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 791 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 792 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 793 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 794 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 795 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 796 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 797 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 798 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 799 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 800 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 801 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 802 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 803 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 804 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 805 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 806 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 807 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 808 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 809 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 810 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 811 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 812 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 813 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 814 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 815 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 816 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 817 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 818 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 819 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 820 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 821 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 822 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 823 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 824 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 825 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 826 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 827 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 828 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 829 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 830 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 831 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 832 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 833 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 834 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 835 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 836 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 837 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 838 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 839 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 840 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 841 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 842 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 843 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 844 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 845 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 846 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 847 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 848 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 849 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 850 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 851 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 852 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 853 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 854 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 855 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 856 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 857 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 858 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 859 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 860 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 861 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 862 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 863 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 864 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 865 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 866 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 867 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 868 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 869 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 870 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 871 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 872 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 873 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 874 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 875 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 876 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 877 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 878 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 879 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 880 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 881 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 882 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 883 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 884 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 885 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 886 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 887 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 888 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 889 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 890 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 891 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 892 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 893 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 894 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 895 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 896 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 897 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 898 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 899 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 900 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 901 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 902 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 903 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 904 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 905 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 906 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 907 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 908 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 909 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 910 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 911 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 912 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 913 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 914 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 915 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 916 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 917 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 918 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 919 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 920 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 921 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 922 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 923 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 924 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 925 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 926 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 927 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 928 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 929 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 930 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 931 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 932 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 933 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 934 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 935 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 936 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 937 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 938 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 939 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 940 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 941 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 942 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 943 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 944 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 945 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 946 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 947 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 948 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 949 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 950 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 951 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 952 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 953 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 954 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 955 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 956 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 957 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 958 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 959 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 960 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 961 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 962 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 963 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 964 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 965 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 966 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 967 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 968 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 969 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 970 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 971 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 972 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 973 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 974 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 975 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 976 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 977 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 978 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 979 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 980 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 981 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 982 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 983 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 984 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 985 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 986 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 987 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 988 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 989 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 990 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 991 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 992 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 993 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 994 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 995 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 996 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 997 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 998 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 999 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1000 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1001 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1002 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1003 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1004 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1005 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1006 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1007 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1008 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1009 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1010 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1011 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1012 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1013 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1014 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1015 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1016 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1017 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1018 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1019 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1020 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1021 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1022 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1023 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1024 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1025 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1026 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1027 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1028 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1029 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1030 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1031 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1032 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1033 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1034 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1035 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1036 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1037 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1038 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1039 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1040 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1041 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1042 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1043 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1044 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1045 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1046 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1047 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1048 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1049 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1050 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1051 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1052 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1053 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1054 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1055 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1056 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1057 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1058 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1059 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1060 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1061 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1062 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1063 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1064 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1065 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1066 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1067 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1068 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1069 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1070 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1071 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1072 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1073 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1074 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1075 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1076 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1077 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1078 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1079 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1080 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1081 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1082 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1083 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1084 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1085 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1086 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1087 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1088 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1089 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1090 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1091 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1092 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1093 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1094 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1095 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1096 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1097 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1098 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1099 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1100 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1101 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1102 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1103 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1104 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1105 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1106 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1107 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1108 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1109 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1110 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1111 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1112 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1113 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1114 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1115 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1116 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1117 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1118 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1119 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1120 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1121 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1122 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1123 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1124 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1125 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1126 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1127 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1128 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1129 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1130 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1131 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1132 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1133 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1134 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1135 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1136 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1137 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1138 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1139 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1140 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1141 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1142 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1143 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1144 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1145 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1146 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1147 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1148 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1149 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1150 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1151 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1152 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1153 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1154 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1155 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1156 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1157 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1158 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1159 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1160 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1161 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1162 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1163 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1164 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1165 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1166 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1167 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1168 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1169 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1170 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1171 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1172 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1173 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1174 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1175 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1176 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1177 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1178 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1179 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1180 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1181 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1182 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1183 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1184 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1185 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1186 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1187 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1188 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1189 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1190 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1191 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1192 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1193 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1194 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1195 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1196 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1197 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1198 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1199 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1200 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1201 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1202 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1203 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1204 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1205 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1206 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1207 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1208 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1209 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1210 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1211 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1212 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1213 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1214 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1215 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1216 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1217 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1218 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1219 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1220 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1221 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1222 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1223 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1224 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1225 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1226 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1227 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1228 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1229 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1230 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1231 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1232 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1233 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1234 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1235 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1236 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1237 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1238 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1239 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1240 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1241 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1242 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1243 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1244 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1245 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1246 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1247 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1248 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1249 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1250 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1251 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1252 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1253 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1254 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1255 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1256 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1257 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1258 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1259 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1260 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1261 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1262 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1263 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1264 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1265 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1266 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1267 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1268 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1269 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1270 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1271 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1272 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1273 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1274 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1275 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1276 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1277 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1278 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1279 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1280 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 Bonds 1 1 6 10 2 1 16 20 3 1 26 30 4 1 36 40 5 1 46 50 6 1 56 60 7 1 66 70 8 1 76 80 9 1 86 90 10 1 96 100 11 1 106 110 12 1 116 120 13 1 126 130 14 1 136 140 15 1 146 150 16 1 156 160 17 1 166 170 18 1 176 180 19 1 186 190 20 1 196 200 21 1 206 210 22 1 216 220 23 1 226 230 24 1 236 240 25 1 246 250 26 1 256 260 27 1 266 270 28 1 276 280 29 1 286 290 30 1 296 300 31 1 306 310 32 1 316 320 33 1 326 330 34 1 336 340 35 1 346 350 36 1 356 360 37 1 366 370 38 1 376 380 39 1 386 390 40 1 396 400 41 1 406 410 42 1 416 420 43 1 426 430 44 1 436 440 45 1 446 450 46 1 456 460 47 1 466 470 48 1 476 480 49 1 486 490 50 1 496 500 51 1 506 510 52 1 516 520 53 1 526 530 54 1 536 540 55 1 546 550 56 1 556 560 57 1 566 570 58 1 576 580 59 1 586 590 60 1 596 600 61 1 606 610 62 1 616 620 63 1 626 630 64 1 636 640 65 1 646 650 66 1 656 660 67 1 666 670 68 1 676 680 69 1 686 690 70 1 696 700 71 1 706 710 72 1 716 720 73 1 726 730 74 1 736 740 75 1 746 750 76 1 756 760 77 1 766 770 78 1 776 780 79 1 786 790 80 1 796 800 81 1 806 810 82 1 816 820 83 1 826 830 84 1 836 840 85 1 846 850 86 1 856 860 87 1 866 870 88 1 876 880 89 1 886 890 90 1 896 900 91 1 906 910 92 1 916 920 93 1 926 930 94 1 936 940 95 1 946 950 96 1 956 960 97 1 966 970 98 1 976 980 99 1 986 990 100 1 996 1000 101 1 1006 1010 102 1 1016 1020 103 1 1026 1030 104 1 1036 1040 105 1 1046 1050 106 1 1056 1060 107 1 1066 1070 108 1 1076 1080 109 1 1086 1090 110 1 1096 1100 111 1 1106 1110 112 1 1116 1120 113 1 1126 1130 114 1 1136 1140 115 1 1146 1150 116 1 1156 1160 117 1 1166 1170 118 1 1176 1180 119 1 1186 1190 120 1 1196 1200 121 1 1206 1210 122 1 1216 1220 123 1 1226 1230 124 1 1236 1240 125 1 1246 1250 126 1 1256 1260 127 1 1266 1270 128 1 1276 1280