diff --git a/doc/src/Section_commands.txt b/doc/src/Section_commands.txt index bcffc3054..0fbab732c 100644 --- a/doc/src/Section_commands.txt +++ b/doc/src/Section_commands.txt @@ -1,1231 +1,1231 @@ "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.html 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 core LAMMPS commands, grouped by category. The "next section"_#cmd_5 lists all commands alphabetically. The next section also includes (long) lists of style options for entries that appear in the following categories as a single command (fix, compute, pair, etc). Commands that are added by user packages are not included in the categories here, but they are in the next section. Initialization: "newton"_newton.html, "package"_package.html, "processors"_processors.html, "suffix"_suffix.html, "units"_units.html Setup simulation box: "boundary"_boundary.html, "box"_box.html, "change_box"_change_box.html, "create_box"_create_box.html, "dimension"_dimension.html, "lattice"_lattice.html, "region"_region.html Setup atoms: "atom_modify"_atom_modify.html, "atom_style"_atom_style.html, "balance"_balance.html, "create_atoms"_create_atoms.html, "create_bonds"_create_bonds.html, "delete_atoms"_delete_atoms.html, "delete_bonds"_delete_bonds.html, "displace_atoms"_displace_atoms.html, "group"_group.html, "mass"_mass.html, "molecule"_molecule.html, "read_data"_read_data.html, "read_dump"_read_dump.html, "read_restart"_read_restart.html, "replicate"_replicate.html, "set"_set.html, "velocity"_velocity.html Force fields: "angle_coeff"_angle_coeff.html, "angle_style"_angle_style.html, "bond_coeff"_bond_coeff.html, "bond_style"_bond_style.html, "bond_write"_bond_write.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_modify"_comm_modify.html, "comm_style"_comm_style.html, "info"_info.html, "min_modify"_min_modify.html, "min_style"_min_style.html, "neigh_modify"_neigh_modify.html, "neighbor"_neighbor.html, "partition"_partition.html, "reset_timestep"_reset_timestep.html, "run_style"_run_style.html, "timer"_timer.html, "timestep"_timestep.html Operations within timestepping (fixes) and diagnostics (computes): "compute"_compute.html, "compute_modify"_compute_modify.html, "fix"_fix.html, "fix_modify"_fix_modify.html, "uncompute"_uncompute.html, "unfix"_unfix.html Output: "dump image"_dump_image.html, "dump movie"_dump_image.html, "dump"_dump.html, "dump_modify"_dump_modify.html, "restart"_restart.html, "thermo"_thermo.html, "thermo_modify"_thermo_modify.html, "thermo_style"_thermo_style.html, "undump"_undump.html, "write_coeff"_write_coeff.html, "write_data"_write_data.html, "write_dump"_write_dump.html, "write_restart"_write_restart.html Actions: "minimize"_minimize.html, "neb"_neb.html, "prd"_prd.html, "rerun"_rerun.html, "run"_run.html, "tad"_tad.html, "temper"_temper.html Input script control: "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, "python"_python.html, "quit"_quit.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 netcdf"_dump_netcdf.html, "dump netcdf/mpiio"_dump_netcdf.html, "dump vtk"_dump_vtk.html, "group2ndx"_group2ndx.html, "ndx2group"_group2ndx.html, "temper/grem"_temper_grem.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, "halt"_fix_halt.html, "heat"_fix_heat.html, "indent"_fix_indent.html, "langevin (k)"_fix_langevin.html, "lineforce"_fix_lineforce.html, "momentum (k)"_fix_momentum.html, "move"_fix_move.html, "mscg"_fix_mscg.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, "python"_fix_python.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 (o)"_fix_rigid.html, "rigid/small/npt (o)"_fix_rigid.html, "rigid/small/nve (o)"_fix_rigid.html, "rigid/small/nvt (o)"_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, "dpd/energy"_fix_dpd_energy.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, "filter/corotate"_fix_filter_corotate.html, "flow/gauss"_fix_flow_gauss.html, "gle"_fix_gle.html, "grem"_fix_grem.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/dot"_fix_nve_dot.html, "nve/dotc/langevin"_fix_nve_dotc_langevin.html, "nve/manifold/rattle"_fix_nve_manifold_rattle.html, "nvk"_fix_nvk.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 (ko)"_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, "global/atom"_compute_global_atom.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, "cnp/atom"_compute_cnp_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/dsf"_pair_born.html, "born/coul/dsf/cs"_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 (go)"_pair_dpd.html, "dpd/tstat (go)"_pair_dpd.html, "dsmc"_pair_dsmc.html, "eam (gkiot)"_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, "gw"_pair_gw.html, "gw/zbl"_pair_gw.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/charmmfsw/coul/charmmfsh"_pair_charmm.html, "lj/charmmfsw/coul/long"_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 (io)"_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 (gkot)"_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, "python"_pair_python.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/mod/c (o)"_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 (ko)"_pair_vashishta.html, "vashishta/table (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. "agni (o)"_pair_agni.html, "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, "edip/multi"_pair_edip.html, "eff/cut"_pair_eff.html, "exp6/rx"_pair_exp6_rx.html, "gauss/cut"_pair_gauss.html, "kolmogorov/crespi/z"_pair_kolmogorov_crespi_z.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, "meam/spline (o)"_pair_meam_spline.html, "meam/sw/spline"_pair_meam_sw_spline.html, "mgpt"_pair_mgpt.html, "momb"_pair_momb.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, "oxdna/coaxstk"_pair_oxdna.html, "oxdna/excv"_pair_oxdna.html, "oxdna/hbond"_pair_oxdna.html, "oxdna/stk"_pair_oxdna.html, "oxdna/xstk"_pair_oxdna.html, "oxdna2/coaxstk"_pair_oxdna2.html, "oxdna2/dh"_pair_oxdna2.html, "oxdna2/excv"_pair_oxdna2.html, "oxdna2/stk"_pair_oxdna2.html, "quip"_pair_quip.html, "reax/c (ko)"_pair_reaxc.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) +"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 (ko)"_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, "oxdna/fene"_bond_oxdna.html, "oxdna2/fene"_bond_oxdna.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 (ko)"_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, "charmmfsw"_dihedral_charmm.html, "class2 (ko)"_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 (ko)"_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 (i)"_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_howto.txt b/doc/src/Section_howto.txt index 579cb6847..f2f2561af 100644 --- a/doc/src/Section_howto.txt +++ b/doc/src/Section_howto.txt @@ -1,2935 +1,2935 @@ "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 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 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 timestep 0.012 :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 special_bonds 0.0 1.0 1.0 :pre read_data tmp.restart.data :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 timestep 0.012 :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. See the "atom_style sphere"_atom_style.html and "fix nve/sphere"_fix_nve_sphere.html commands for details. By default, for 2d simulations, such particles will still be modeled as 3d spheres, not 2d discs (circles), meaning their moment of inertia will be that of a sphere. If you wish to model them as 2d discs, see the "set density/disc"_set.html command and the {disc} option for the "fix nve/sphere"_fix_nve_sphere.html, "fix nvt/sphere"_fix_nvt_sphere.html, "fix nph/sphere"_fix_nph_sphere.html, "fix npt/sphere"_fix_npt_sphere.html commands. :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 charmmfsh "dihedral_style"_dihedral_charmm.html charmm "pair_style"_pair_charmm.html lj/charmmfsw/coul/charmmfsh "pair_style"_pair_charmm.html lj/charmmfsw/coul/long "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 NOTE: For CHARMM, newer {charmmfsw} or {charmmfsh} styles were released in March 2017. We recommend they be used instead of the older {charmm} styles. See discussion of the differences on the "pair charmm"_pair_charmm.html and "dihedral charmm"_dihedral_charmm.html doc pages. 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 NOTE: By default, for 2d systems, granular particles are still modeled as 3d spheres, not 2d discs (circles), meaning their moment of inertia will be the same as in 3d. If you wish to model granular particles in 2d as 2d discs, see the note on this topic in "Section 6.2"_Section_howto.html#howto_2, where 2d simulations are disussed. :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)"_#Jorgensen1. 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)"_#Price1 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)"_#Jorgensen1. 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 neighbor 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 assignments 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 several popular visualization tools. The "dump image"_dump_image.html and "dump movie"_dump_image.html styles can output internally rendered images and convert a sequence of them to a movie during the MD run. Several programs included with LAMMPS as auxiliary tools can convert between LAMMPS format files and other formats. See the "Section 9"_Section_tools.html doc page for details. 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. :link(pizza,http://www.sandia.gov/~sjplimp/pizza.html) :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 simulation 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 dynamics 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 analog 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. NEMD simulations can also be used to measure transport properties of a fluid through a pore or channel. Simulations of steady-state flow can be performed using the "fix flow/gauss"_fix_flow_gauss.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 enumerate 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, respectively, 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 motion 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 analogous 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 calculated 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/berendsen"_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)"_#Shinoda1 :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 functions for creating and destroying an instance of LAMMPS and sending it commands to execute. See the documentation in the src/library.cpp file for details: void lammps_open(int, char **, MPI_Comm, void **) void lammps_open_no_mpi(int, char **, void **) void lammps_close(void *) int lammps_version(void *) void lammps_file(void *, char *) char *lammps_command(void *, char *) void lammps_commands_list(void *, int, char **) void lammps_commands_string(void *, char *) void lammps_free(void *) :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_open_no_mpi() function is similar except that no MPI communicator is passed from the caller. Instead, MPI_COMM_WORLD is used to instantiate LAMMPS, and MPI is initialized if necessary. 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(), lammps_command(), lammps_commands_list(), and lammps_commands_string() functions are used to pass one or more commands to LAMMPS to execute, the same as if they were coming from an input script. Via these functions, the calling code can read or generate a series of LAMMPS commands one or multiple at a time and pass it thru the library interface to setup a problem and then run it in stages. The caller can interleave the command function calls with operations it performs, calls to extract information from or set information within LAMMPS, or calls to another code's library. The lammps_file() function passes the filename of an input script. The lammps_command() function passes a single command as a string. The lammps_commands_list() function passes multiple commands in a char** list. In both lammps_command() and lammps_commands_list(), individual commands may or may not have a trailing newline. The lammps_commands_string() function passes multiple commands concatenated into one long string, separated by newline characters. In both lammps_commands_list() and lammps_commands_string(), a single command can be spread across multiple lines, if the last printable character of all but the last line is "&", the same as if the lines appeared in an input script. The lammps_free() function is a clean-up function to free memory that the library allocated previously via other function calls. See comments in src/library.cpp file for which other functions need this clean-up. Library.cpp also contains these functions for extracting information from LAMMPS and setting value within LAMMPS. Again, see the documentation in the src/library.cpp file for details, including which quantities can be queried by name: void *lammps_extract_global(void *, char *) -void lammps_extract_box(void *, double *, double *, +void lammps_extract_box(void *, double *, double *, double *, double *, double *, int *, int *) 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 *) :pre void lammps_reset_box(void *, double *, double *, double, double, double) int lammps_set_variable(void *, char *, char *) :pre double lammps_get_thermo(void *, char *) int lammps_get_natoms(void *) void lammps_gather_atoms(void *, double *) void lammps_scatter_atoms(void *, double *) :pre void lammps_create_atoms(void *, int, tagint *, int *, double *, double *, imageint *, int) :pre The extract functions return a pointer to various global or per-atom quantities stored in LAMMPS or to values calculated by a compute, fix, or variable. The pointer returned by the extract_global() function can be used as a permanent reference to a value which may change. For the extract_atom() method, see the extract() method in the src/atom.cpp file for a list of valid per-atom properties. New names could easily be added if the property you want is not listed. For the other extract functions, the underlying storage may be reallocated as LAMMPS runs, so you need to re-call the function to assure a current pointer or returned value(s). The lammps_reset_box() function resets the size and shape of the simulation box, e.g. as part of restoring a previously extracted and saved state of a simulation. The lammps_set_variable() function can set an existing string-style variable to a new string value, so that subsequent LAMMPS commands can access the variable. The lammps_get_thermo() function returns the current value of a thermo keyword as a double precision value. The lammps_get_natoms() function returns the total number of atoms in the system and can be used by the caller to allocate space for the lammps_gather_atoms() and lammps_scatter_atoms() functions. The gather function collects peratom info of the requested type (atom coords, types, forces, etc) from all processors, orders them by atom ID, and returns a full list to each calling processor. The scatter function does the inverse. It distributes the same peratom values, passed by the caller, to each atom owned by individual processors. Both methods are thus a means to extract or assign (overwrite) any peratom quantities within LAMMPS. See the extract() method in the src/atom.cpp file for a list of valid per-atom properties. New names could easily be added if the property you want is not listed. A special treatment is applied for accessing image flags via the "image" property. Image flags are stored in a packed format with all three image flags stored in a single integer. When signaling to access the image flags as 3 individual values per atom instead of 1, the data is transparently packed or unpacked by the library interface. The lammps_create_atoms() function takes a list of N atoms as input with atom types and coords (required), an optionally atom IDs and velocities and image flags. It uses the coords of each atom to assign it as a new atom to the processor that owns it. This function is useful to add atoms to a simulation or (in tandem with lammps_reset_box()) to restore a previously extracted and saved state of a simulation. Additional properties for the new atoms can then be assigned via the lammps_scatter_atoms() or lammps_extract_atom() functions. 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. NOTE: You can write code for additional functions as needed 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 added functions can access or change any LAMMPS data you wish. :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 conductivity 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-equilibrium 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 cumulative 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 pair_style lj/cut 13.0 pair_coeff * * 0.2381 3.405 timestep $\{dt\} 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 integers. 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 examples 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 dependent 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, parameters 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 coefficients 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 environments. 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 polarizable 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 Fincham"_#MitchellFincham 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. The relative motion of -the core and shell particles corresponds to the polarization, -hereby an instantaneous relaxation of the shells is approximated +the core and shell particles corresponds to the polarization, +hereby an instantaneous relaxation of the shells is approximated and a fast core/shell spring frequency ensures a nearly constant -internal kinetic energy during the simulation. +internal kinetic energy during the simulation. Thermostats can alter this polarization behaviour, by scaling the -internal kinetic energy, meaning the shell will not react freely to -its electrostatic environment. -Therefore it is typically desirable to decouple the relative motion of +internal kinetic energy, meaning the shell will not react freely to +its electrostatic environment. +Therefore it is 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 -The pressure for the core/shell system is computed via the regular -LAMMPS convention by "treating the cores and shells as individual -particles"_#MitchellFincham2. For the thermo output of the pressure -as well as for the application of a barostat, it is necessary to -use an additional "pressure"_compute_pressure compute based on the -default "temperature"_compute_temp and specifying it as a second -argument in "fix modify"_fix_modify.html and +The pressure for the core/shell system is computed via the regular +LAMMPS convention by "treating the cores and shells as individual +particles"_#MitchellFincham2. For the thermo output of the pressure +as well as for the application of a barostat, it is necessary to +use an additional "pressure"_compute_pressure compute based on the +default "temperature"_compute_temp and specifying it as a second +argument in "fix modify"_fix_modify.html and "thermo_modify"_thermo_modify.html resulting in: (...) compute CSequ all temp/cs cores shells compute thermo_press_lmp all pressure thermo_temp # pressure for individual particles thermo_modify temp CSequ press thermo_press_lmp # modify thermo to regular pressure fix press_bar all npt temp 300 300 0.04 iso 0 0 0.4 fix_modify press_bar temp CSequ press thermo_press_lmp # pressure modification for correct kinetic scalar :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 recommendable 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 initializing 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 command, e.g. velocity all create 1427 134 bias yes temp CSequ velocity all scale 1427 temp CSequ :pre -To maintain the correct polarizability of the core/shell pairs, the -kinetic energy of the internal motion shall remain nearly constant. -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 allows the shells to -effectively react instantaneously to the electrostatic environment and +To maintain the correct polarizability of the core/shell pairs, the +kinetic energy of the internal motion shall remain nearly constant. +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 allows the shells to +effectively react instantaneously to the electrostatic environment and limits energy transfer to or from the core/shell oscillators. This fast movement also dictates the timestep 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. +energy transfer to the environment. The mentioned energy transfer will typically lead to 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 if core/shell pairs are the only molecules: -read_data NaCl_CS_x0.1_prop.data +read_data NaCl_CS_x0.1_prop.data compute prop all property/atom molecule 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 For example if core/shell pairs and other molecules are present: 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 (...) :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, represents 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 "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(Jorgensen1) [(Jorgensen)] Jorgensen, Chandrasekhar, Madura, Impey, Klein, J Chem Phys, 79, 926 (1983). :link(Price1) [(Price)] Price and Brooks, J Chem Phys, 121, 10096 (2004). :link(Shinoda1) [(Shinoda)] Shinoda, Shiga, and Mikami, Phys Rev B, 69, 134103 (2004). :link(MitchellFincham) [(Mitchell and Fincham)] Mitchell, Fincham, J Phys Condensed Matter, 5, 1031-1038 (1993). :link(MitchellFincham2) [(Fincham)] Fincham, Mackrodt and Mitchell, J Phys Condensed Matter, 6, 393-404 (1994). :link(howto-Lamoureux) [(Lamoureux and Roux)] G. Lamoureux, B. Roux, J. Chem. Phys 119, 3025 (2003) diff --git a/doc/src/Section_packages.txt b/doc/src/Section_packages.txt index 14b2c0baa..24506379c 100644 --- a/doc/src/Section_packages.txt +++ b/doc/src/Section_packages.txt @@ -1,2602 +1,2602 @@ "Previous Section"_Section_commands.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next Section"_Section_accelerate.html :c :link(lws,http://lammps.sandia.gov) :link(ld,Manual.html) :link(lc,Section_commands.html#comm) :line 4. Packages :h3 This section gives an overview of the optional packages that extend LAMMPS functionality with instructions on how to build LAMMPS with each of them. Packages are groups of files that enable a specific set of features. For example, force fields for molecular systems or granular systems are in packages. You can see the list of all packages and "make" commands to manage them by typing "make package" from within the src directory of the LAMMPS distribution. "Section 2.3"_Section_start.html#start_3 gives general info on how to install and un-install packages as part of the LAMMPS build process. There are two kinds of packages in LAMMPS, standard and user packages: "Table of standard packages"_#table_standard "Table of user packages"_#table_user :ul Standard packages are supported by the LAMMPS developers and are written in a syntax and style consistent with the rest of LAMMPS. This means the developers will answer questions about them, debug and fix them if necessary, and keep them compatible with future changes to LAMMPS. User packages have been contributed by users, and begin with the "user" prefix. If they are a single command (single file), they are typically in the user-misc package. User packages don't necessarily meet the requirements of the standard packages. If you have problems using a feature provided in a user package, you may need to contact the contributor directly to get help. Information on how to submit additions you make to LAMMPS as single files or as a standard or user package are given in "this section"_Section_modify.html#mod_15 of the manual. Following the next two tables is a sub-section for each package. It lists authors (if applicable) and summarizes the package contents. It has specific instructions on how to install the package, including (if necessary) downloading or building any extra library it requires. It also gives links to documentation, example scripts, and pictures/movies (if available) that illustrate use of the package. NOTE: To see the complete list of commands a package adds to LAMMPS, just look at the files in its src directory, e.g. "ls src/GRANULAR". Files with names that start with fix, compute, atom, pair, bond, angle, etc correspond to commands with the same style names. In these two tables, the "Example" column is a sub-directory in the examples directory of the distribution which has an input script that uses the package. E.g. "peptide" refers to the examples/peptide directory; USER/atc refers to the examples/USER/atc directory. The "Library" column indicates whether an extra library is needed to build and use the package: dash = no library sys = system library: you likely have it on your machine int = internal library: provided with LAMMPS, but you may need to build it ext = external library: you will need to download and install it on your machine :ul :line :line [Standard packages] :link(table_standard),p Package, Description, Doc page, Example, Library "ASPHERE"_#ASPHERE, aspherical particle models, "Section 6.6.14"_Section_howto.html#howto_14, ellipse, - "BODY"_#BODY, body-style particles, "body"_body.html, body, - "CLASS2"_#CLASS2, class 2 force fields, "pair_style lj/class2"_pair_class2.html, -, - "COLLOID"_#COLLOID, colloidal particles, "atom_style colloid"_atom_style.html, colloid, - "COMPRESS"_#COMPRESS, I/O compression, "dump */gz"_dump.html, -, sys "CORESHELL"_#CORESHELL, adiabatic core/shell model, "Section 6.6.25"_Section_howto.html#howto_25, coreshell, - "DIPOLE"_#DIPOLE, point dipole particles, "pair_style dipole/cut"_pair_dipole.html, dipole, - "GPU"_#GPU, GPU-enabled styles, "Section 5.3.1"_accelerate_gpu.html, WWW bench, int "GRANULAR"_#GRANULAR, granular systems, "Section 6.6.6"_Section_howto.html#howto_6, pour, - "KIM"_#KIM, openKIM wrapper, "pair_style kim"_pair_kim.html, kim, ext "KOKKOS"_#KOKKOS, Kokkos-enabled styles, "Section 5.3.3"_accelerate_kokkos.html, WWW bench, - "KSPACE"_#KSPACE, long-range Coulombic solvers, "kspace_style"_kspace_style.html, peptide, - "MANYBODY"_#MANYBODY, many-body potentials, "pair_style tersoff"_pair_tersoff.html, shear, - "MC"_#MC, Monte Carlo options, "fix gcmc"_fix_gcmc.html, -, - "MEAM"_#MEAM, modified EAM potential, "pair_style meam"_pair_meam.html, meam, int "MISC"_#MISC, miscellanous single-file commands, -, -, - "MOLECULE"_#MOLECULE, molecular system force fields, "Section 6.6.3"_Section_howto.html#howto_3, peptide, - "MPIIO"_#MPIIO, MPI parallel I/O dump and restart, "dump"_dump.html, -, - "MSCG"_#MSCG, multi-scale coarse-graining wrapper, "fix mscg"_fix_mscg.html, mscg, ext "OPT"_#OPT, optimized pair styles, "Section 5.3.5"_accelerate_opt.html, WWW bench, - "PERI"_#PERI, Peridynamics models, "pair_style peri"_pair_peri.html, peri, - "POEMS"_#POEMS, coupled rigid body motion, "fix poems"_fix_poems.html, rigid, int "PYTHON"_#PYTHON, embed Python code in an input script, "python"_python.html, python, sys "QEQ"_#QEQ, QEq charge equilibration, "fix qeq"_fix_qeq.html, qeq, - "REAX"_#REAX, ReaxFF potential (Fortran), "pair_style reax"_pair_reax.html, reax, int "REPLICA"_#REPLICA, multi-replica methods, "Section 6.6.5"_Section_howto.html#howto_5, tad, - "RIGID"_#RIGID, rigid bodies and constraints, "fix rigid"_fix_rigid.html, rigid, - "SHOCK"_#SHOCK, shock loading methods, "fix msst"_fix_msst.html, -, - "SNAP"_#SNAP, quantum-fitted potential, "pair snap"_pair_snap.html, snap, - "SRD"_#SRD, stochastic rotation dynamics, "fix srd"_fix_srd.html, srd, - "VORONOI"_#VORONOI, Voronoi tesselation, "compute voronoi/atom"_compute_voronoi_atom.html, -, ext :tb(ea=c,ca1=l) [USER packages] :link(table_user),p Package, Description, Doc page, Example, Library "USER-ATC"_#USER-ATC, atom-to-continuum coupling, "fix atc"_fix_atc.html, USER/atc, int "USER-AWPMD"_#USER-AWPMD, wave-packet MD, "pair_style awpmd/cut"_pair_awpmd.html, USER/awpmd, int "USER-CGDNA"_#USER-CGDNA, coarse-grained DNA force fields, src/USER-CGDNA/README, USER/cgdna, - "USER-CGSDK"_#USER-CGSDK, SDK coarse-graining model, "pair_style lj/sdk"_pair_sdk.html, USER/cgsdk, - "USER-COLVARS"_#USER-COLVARS, collective variables library, "fix colvars"_fix_colvars.html, USER/colvars, int "USER-DIFFRACTION"_#USER-DIFFRACTION, virtual x-ray and electron diffraction,"compute xrd"_compute_xrd.html, USER/diffraction, - "USER-DPD"_#USER-DPD, reactive dissipative particle dynamics, src/USER-DPD/README, USER/dpd, - "USER-DRUDE"_#USER-DRUDE, Drude oscillators, "tutorial"_tutorial_drude.html, USER/drude, - "USER-EFF"_#USER-EFF, electron force field,"pair_style eff/cut"_pair_eff.html, USER/eff, - "USER-FEP"_#USER-FEP, free energy perturbation,"compute fep"_compute_fep.html, USER/fep, - "USER-H5MD"_#USER-H5MD, dump output via HDF5,"dump h5md"_dump_h5md.html, -, ext "USER-INTEL"_#USER-INTEL, optimized Intel CPU and KNL styles,"Section 5.3.2"_accelerate_intel.html, WWW bench, - "USER-LB"_#USER-LB, Lattice Boltzmann fluid,"fix lb/fluid"_fix_lb_fluid.html, USER/lb, - "USER-MANIFOLD"_#USER-MANIFOLD, motion on 2d surfaces,"fix manifoldforce"_fix_manifoldforce.html, USER/manifold, - "USER-MGPT"_#USER-MGPT, fast MGPT multi-ion potentials, "pair_style mgpt"_pair_mgpt.html, USER/mgpt, - "USER-MISC"_#USER-MISC, single-file contributions, USER-MISC/README, USER/misc, - "USER-MOLFILE"_#USER-MOLFILE, "VMD"_vmd_home molfile plug-ins,"dump molfile"_dump_molfile.html, -, ext "USER-NETCDF"_#USER-NETCDF, dump output via NetCDF,"dump netcdf"_dump_netcdf.html, -, ext "USER-OMP"_#USER-OMP, OpenMP-enabled styles,"Section 5.3.4"_accelerate_omp.html, WWW bench, - "USER-PHONON"_#USER-PHONON, phonon dynamical matrix,"fix phonon"_fix_phonon.html, USER/phonon, - "USER-QMMM"_#USER-QMMM, QM/MM coupling,"fix qmmm"_fix_qmmm.html, USER/qmmm, ext "USER-QTB"_#USER-QTB, quantum nuclear effects,"fix qtb"_fix_qtb.html "fix qbmsst"_fix_qbmsst.html, qtb, - "USER-QUIP"_#USER-QUIP, QUIP/libatoms interface,"pair_style quip"_pair_quip.html, USER/quip, ext "USER-REAXC"_#USER-REAXC, ReaxFF potential (C/C++) ,"pair_style reaxc"_pair_reaxc.html, reax, - "USER-SMD"_#USER-SMD, smoothed Mach dynamics,"SMD User Guide"_PDF/SMD_LAMMPS_userguide.pdf, USER/smd, ext "USER-SMTBQ"_#USER-SMTBQ, second moment tight binding QEq potential,"pair_style smtbq"_pair_smtbq.html, USER/smtbq, - "USER-SPH"_#USER-SPH, smoothed particle hydrodynamics,"SPH User Guide"_PDF/SPH_LAMMPS_userguide.pdf, USER/sph, - "USER-TALLY"_#USER-TALLY, pairwise tally computes,"compute XXX/tally"_compute_tally.html, USER/tally, - "USER-VTK"_#USER-VTK, dump output via VTK, "compute vtk"_dump_vtk.html, -, ext :tb(ea=c,ca1=l) :line :line ASPHERE package :link(ASPHERE),h4 [Contents:] Computes, time-integration fixes, and pair styles for aspherical particle models including ellipsoids, 2d lines, and 3d triangles. [Install or un-install:] make yes-asphere make machine :pre make no-asphere make machine :pre [Supporting info:] src/ASPHERE: filenames -> commands "Section 6.14"_Section_howto.html#howto_14 "pair_style gayberne"_pair_gayberne.html "pair_style resquared"_pair_resquared.html "doc/PDF/pair_gayberne_extra.pdf"_PDF/pair_gayberne_extra.pdf "doc/PDF/pair_resquared_extra.pdf"_PDF/pair_resquared_extra.pdf examples/ASPHERE examples/ellipse http://lammps.sandia.gov/movies.html#line http://lammps.sandia.gov/movies.html#tri :ul :line BODY package :link(BODY),h4 [Contents:] Body-style particles with internal structure. Computes, time-integration fixes, pair styles, as well as the body styles themselves. See the "body"_body.html doc page for an overview. [Install or un-install:] make yes-body make machine :pre make no-body make machine :pre [Supporting info:] src/BODY filenames -> commands "body"_body.html "atom_style body"_atom_style.html "fix nve/body"_fix_nve_body.html "pair_style body"_pair_body.html examples/body :ul :line CLASS2 package :link(CLASS2),h4 [Contents:] Bond, angle, dihedral, improper, and pair styles for the COMPASS CLASS2 molecular force field. [Install or un-install:] make yes-class2 make machine :pre make no-class2 make machine :pre [Supporting info:] src/CLASS2: filenames -> commands "bond_style class2"_bond_class2.html "angle_style class2"_angle_class2.html "dihedral_style class2"_dihedral_class2.html "improper_style class2"_improper_class2.html "pair_style lj/class2"_pair_class2.html :ul :line COLLOID package :link(COLLOID),h4 [Contents:] Coarse-grained finite-size colloidal particles. Pair stayle and fix wall styles for colloidal interactions. Includes the Fast Lubrication Dynamics (FLD) method for hydrodynamic interactions, which is a simplified approximation to Stokesian dynamics. [Authors:] This package includes Fast Lubrication Dynamics pair styles which were created by Amit Kumar and Michael Bybee from Jonathan Higdon's group at UIUC. [Install or un-install:] make yes-colloid make machine :pre make no-colloid make machine :pre [Supporting info:] src/COLLOID: filenames -> commands "fix wall/colloid"_fix_wall.html "pair_style colloid"_pair_colloid.html "pair_style yukawa/colloid"_pair_yukawa_colloid.html "pair_style brownian"_pair_brownian.html "pair_style lubricate"_pair_lubricate.html "pair_style lubricateU"_pair_lubricateU.html examples/colloid examples/srd :ul :line COMPRESS package :link(COMPRESS),h4 [Contents:] Compressed output of dump files via the zlib compression library, using dump styles with a "gz" in their style name. To use this package you must have the zlib compression library available on your system. [Author:] Axel Kohlmeyer (Temple U). [Install or un-install:] Note that building with this package assumes you have the zlib compression library available on your system. The LAMMPS build uses the settings in the lib/compress/Makefile.lammps file in the compile/link process. You should only need to edit this file if the LAMMPS build fails on your system. make yes-compress make machine :pre make no-compress make machine :pre [Supporting info:] src/COMPRESS: filenames -> commands src/COMPRESS/README lib/compress/README "dump atom/gz"_dump.html "dump cfg/gz"_dump.html "dump custom/gz"_dump.html "dump xyz/gz"_dump.html :ul :line CORESHELL package :link(CORESHELL),h4 [Contents:] Compute and pair styles that implement the adiabatic core/shell model for polarizability. The pair styles augment Born, Buckingham, and Lennard-Jones styles with core/shell capabilities. The "compute temp/cs"_compute_temp_cs.html command calculates the temperature of a system with core/shell particles. See "Section 6.26"_Section_howto.html#howto_26 for an overview of how to use this package. [Author:] Hendrik Heenen (Technical U of Munich). [Install or un-install:] make yes-coreshell make machine :pre make no-coreshell make machine :pre [Supporting info:] src/CORESHELL: filenames -> commands "Section 6.26"_Section_howto.html#howto_26 "Section 6.25"_Section_howto.html#howto_25 "compute temp/cs"_compute_temp_cs.html "pair_style born/coul/long/cs"_pair_cs.html "pair_style buck/coul/long/cs"_pair_cs.html "pair_style lj/cut/coul/long/cs"_pair_lj.html examples/coreshell :ul :line DIPOLE package :link(DIPOLE),h4 [Contents:] An atom style and several pair styles for point dipole models with short-range or long-range interactions. [Install or un-install:] make yes-dipole make machine :pre make no-dipole make machine :pre [Supporting info:] src/DIPOLE: filenames -> commands "atom_style dipole"_atom_style.html "pair_style lj/cut/dipole/cut"_pair_dipole.html "pair_style lj/cut/dipole/long"_pair_dipole.html "pair_style lj/long/dipole/long"_pair_dipole.html examples/dipole :ul :line GPU package :link(GPU),h4 [Contents:] Dozens of pair styles and a version of the PPPM long-range Coulombic solver optimized for NVIDIA GPUs. All such styles have a "gpu" as a suffix in their style name. "Section 5.3.1"_accelerate_gpu.html gives details of what hardware and Cuda software is required on your system, and details on how to build and use this package. Its styles can be invoked at run time via the "-sf gpu" or "-suffix gpu" "command-line switches"_Section_start.html#start_7. See also the "KOKKOS"_#KOKKOS package, which has GPU-enabled styles. [Authors:] Mike Brown (Intel) while at Sandia and ORNL and Trung Nguyen (Northwestern U) while at ORNL. [Install or un-install:] Before building LAMMPS with this package, you must first build the GPU library in lib/gpu from a set of provided C and Cuda files. You can do this manually if you prefer; follow the instructions in lib/gpu/README. You can also do it in one step from the lammps/src dir, using a command like these, which simply invoke the lib/gpu/Install.py script with the specified args: make lib-gpu # print help message make lib-gpu args="-m" # build GPU library with default Makefile.linux make lib-gpu args="-i xk7 -p single -o xk7.single" # create new Makefile.xk7.single, altered for single-precision make lib-gpu args="-i xk7 -p single -o xk7.single -m" # ditto, also build GPU library Note that this procedure starts with one of the existing Makefile.machine files in lib/gpu. It allows you to alter 4 important settings in that Makefile, via the -h, -a, -p, -e switches, and save the new Makefile, if desired: CUDA_HOME = where NVIDIA Cuda software is installed on your system CUDA_ARCH = what GPU hardware you have (see help message for details) CUDA_PRECISION = precision (double, mixed, single) EXTRAMAKE = which Makefile.lammps.* file to copy to Makefile.lammps :ul If the library build is successful, 2 files should be created: lib/gpu/libgpu.a and lib/gpu/Makefile.lammps. The latter has settings that enable LAMMPS to link with Cuda libraries. If the settings in Makefile.lammps for your machine are not correct, the LAMMPS build will fail. You can then install/un-install the package and build LAMMPS in the usual manner: make yes-gpu make machine :pre make no-gpu make machine :pre NOTE: If you re-build the GPU library in lib/gpu, you should always un-install the GPU package, then re-install it and re-build LAMMPS. This is because the compilation of files in the GPU package use the library settings from the lib/gpu/Makefile.machine used to build the GPU library. [Supporting info:] src/GPU: filenames -> commands src/GPU/README lib/gpu/README "Section 5.3"_Section_accelerate.html#acc_3 "Section 5.3.1"_accelerate_gpu.html "Section 2.7 -sf gpu"_Section_start.html#start_7 "Section 2.7 -pk gpu"_Section_start.html#start_7 "package gpu"_package.html Pair Styles section of "Section 3.5"_Section_commands.html#cmd_5 for pair styles followed by (g) "Benchmarks page"_http://lammps.sandia.gov/bench.html of web site :ul :line GRANULAR package :link(GRANULAR),h4 [Contents:] Pair styles and fixes for finite-size granular particles, which interact with each other and boundaries via frictional and dissipative potentials. [Install or un-install:] make yes-granular make machine :pre make no-granular make machine :pre [Supporting info:] src/GRANULAR: filenames -> commands "Section 6.6"_Section_howto.html#howto_6, "fix pour"_fix_pour.html "fix wall/gran"_fix_wall_gran.html "pair_style gran/hooke"_pair_gran.html "pair_style gran/hertz/history"_pair_gran.html examples/granregion examples/pour bench/in.chute http://lammps.sandia.gov/pictures.html#jamming http://lammps.sandia.gov/movies.html#hopper http://lammps.sandia.gov/movies.html#dem http://lammps.sandia.gov/movies.html#brazil http://lammps.sandia.gov/movies.html#granregion :ul :line KIM package :link(KIM),h4 [Contents:] A "pair_style kim"_pair_kim.html command which is a wrapper on the Knowledge Base for Interatomic Models (KIM) repository of interatomic potentials, enabling any of them to be used in LAMMPS simulations. To use this package you must have the KIM library available on your system. Information about the KIM project can be found at its website: https://openkim.org. The KIM project is led by Ellad Tadmor and Ryan Elliott (U Minnesota) and James Sethna (Cornell U). [Authors:] Ryan Elliott (U Minnesota) is the main developer for the KIM API which the "pair_style kim"_pair_kim.html command uses. He developed the pair style in collaboration with Valeriu Smirichinski (U Minnesota). [Install or un-install:] Using this package requires the KIM library and its models (interatomic potentials) to be downloaded and installed on your system. The library can be downloaded and built in lib/kim or elsewhere on your system. Details of the download, build, and install process for KIM are given in the lib/kim/README file. Once that process is complete, you can then install/un-install the package and build LAMMPS in the usual manner: make yes-kim make machine :pre make no-kim make machine :pre [Supporting info:] src/KIM: filenames -> commands src/KIM/README lib/kim/README "pair_style kim"_pair_kim.html examples/kim :ul :line KOKKOS package :link(KOKKOS),h4 [Contents:] Dozens of atom, pair, bond, angle, dihedral, improper, fix, compute styles adapted to compile using the Kokkos library which can convert them to OpenMP or Cuda code so that they run efficiently on multicore CPUs, KNLs, or GPUs. All the styles have a "kk" as a suffix in their style name. "Section 5.3.3"_accelerate_kokkos.html gives details of what hardware and software is required on your system, and how to build and use this package. Its styles can be invoked at run time via the "-sf kk" or "-suffix kk" "command-line switches"_Section_start.html#start_7. Also see the "GPU"_#GPU, "OPT"_#OPT, "USER-INTEL"_#USER-INTEL, and "USER-OMP"_#USER-OMP packages, which have styles optimized for CPUs, KNLs, and GPUs. You must have a C++11 compatible compiler to use this package. [Authors:] The KOKKOS package was created primarily by Christian Trott and Stan Moore (Sandia), with contributions from other folks as well. It uses the open-source "Kokkos library"_https://github.com/kokkos which was developed by Carter Edwards, Christian Trott, and others at Sandia, and which is included in the LAMMPS distribution in lib/kokkos. [Install or un-install:] For the KOKKOS package, you have 3 choices when building. You can build with either CPU or KNL or GPU support. Each choice requires additional settings in your Makefile.machine for the KOKKOS_DEVICES and KOKKOS_ARCH settings. See the src/MAKE/OPTIONS/Makefile.kokkos* files for examples. For multicore CPUs using OpenMP: KOKKOS_DEVICES = OpenMP KOKKOS_ARCH = HSW # HSW = Haswell, SNB = SandyBridge, BDW = Broadwell, etc For Intel KNLs using OpenMP: KOKKOS_DEVICES = OpenMP KOKKOS_ARCH = KNL For NVIDIA GPUs using Cuda: KOKKOS_DEVICES = Cuda KOKKOS_ARCH = Pascal60,Power8 # P100 hosted by an IBM Power8, etc KOKKOS_ARCH = Kepler37,Power8 # K80 hosted by an IBM Power8, etc For GPUs, you also need these 2 lines in your Makefile.machine before the CC line is defined, in this case for use with OpenMPI mpicxx. The 2 lines define a nvcc wrapper compiler, which will use nvcc for compiling Cuda files or use a C++ compiler for non-Kokkos, non-Cuda files. KOKKOS_ABSOLUTE_PATH = $(shell cd $(KOKKOS_PATH); pwd) export OMPI_CXX = $(KOKKOS_ABSOLUTE_PATH)/config/nvcc_wrapper CC = mpicxx Once you have an appropriate Makefile.machine, you can install/un-install the package and build LAMMPS in the usual manner. Note that you cannot build one executable to run on multiple hardware targets (CPU or KNL or GPU). You need to build LAMMPS once for each hardware target, to produce a separate executable. Also note that we do not recommend building with other acceleration packages installed (GPU, OPT, USER-INTEL, USER-OMP) when also building with KOKKOS. make yes-kokkos make machine :pre - + make no-kokkos make machine :pre [Supporting info:] src/KOKKOS: filenames -> commands src/KOKKOS/README lib/kokkos/README "Section 5.3"_Section_accelerate.html#acc_3 "Section 5.3.3"_accelerate_kokkos.html "Section 2.7 -k on ..."_Section_start.html#start_7 "Section 2.7 -sf kk"_Section_start.html#start_7 "Section 2.7 -pk kokkos"_Section_start.html#start_7 "package kokkos"_package.html Styles sections of "Section 3.5"_Section_commands.html#cmd_5 for styles followed by (k) "Benchmarks page"_http://lammps.sandia.gov/bench.html of web site :ul :line KSPACE package :link(KSPACE),h4 [Contents:] A variety of long-range Coulombic solvers, as well as pair styles which compute the corresponding short-range pairwise Coulombic interactions. These include Ewald, particle-particle particle-mesh (PPPM), and multilevel summation method (MSM) solvers. [Install or un-install:] Building with this package requires a 1d FFT library be present on your system for use by the PPPM solvers. This can be the KISS FFT library provided with LAMMPS, 3rd party libraries like FFTW, or a vendor-supplied FFT library. See step 6 of "Section 2.2.2"_Section_start.html#start_2_2 of the manual for details on how to select different FFT options in your machine Makefile. make yes-kspace make machine :pre make no-kspace make machine :pre [Supporting info:] src/KSPACE: filenames -> commands "kspace_style"_kspace_style.html "doc/PDF/kspace.pdf"_PDF/kspace.pdf "Section 6.7"_Section_howto.html#howto_7 "Section 6.8"_Section_howto.html#howto_8 "Section 6.9"_Section_howto.html#howto_9 "pair_style coul"_pair_coul.html Pair Styles section of "Section 3.5"_Section_commands.html#cmd_5 with "long" or "msm" in pair style name examples/peptide bench/in.rhodo :ul :line MANYBODY package :link(MANYBODY),h4 [Contents:] A variety of manybody and bond-order potentials. These include (AI)REBO, BOP, EAM, EIM, Stillinger-Weber, and Tersoff potentials. [Install or un-install:] make yes-manybody make machine :pre make no-manybody make machine :pre [Supporting info:] src/MANYBODY: filenames -> commands Pair Styles section of "Section 3.5"_Section_commands.html#cmd_5 examples/comb examples/eim examples/nb3d examples/shear examples/streitz examples/vashishta bench/in.eam :ul :line MC package :link(MC),h4 [Contents:] Several fixes and a pair style that have Monte Carlo (MC) or MC-like attributes. These include fixes for creating, breaking, and swapping bonds, for performing atomic swaps, and performing grand-canonical MC (GCMC) in conjuction with dynamics. [Install or un-install:] make yes-mc make machine :pre make no-mc make machine :pre [Supporting info:] src/MC: filenames -> commands "fix atom/swap"_fix_atom_swap.html "fix bond/break"_fix_bond_break.html "fix bond/create"_fix_bond_create.html "fix bond/swap"_fix_bond_swap.html "fix gcmc"_fix_gcmc.html "pair_style dsmc"_pair_dsmc.html http://lammps.sandia.gov/movies.html#gcmc :ul :line MEAM package :link(MEAM),h4 [Contents:] A pair style for the modified embedded atom (MEAM) potential. [Author:] Greg Wagner (Northwestern U) while at Sandia. [Install or un-install:] Before building LAMMPS with this package, you must first build the MEAM library in lib/meam. You can do this manually if you prefer; follow the instructions in lib/meam/README. You can also do it in one step from the lammps/src dir, using a command like these, which simply invoke the lib/meam/Install.py script with the specified args: make lib-meam # print help message make lib-meam args="-m gfortran" # build with GNU Fortran compiler make lib-meam args="-m ifort" # build with Intel ifort compiler :pre The build should produce two files: lib/meam/libmeam.a and lib/meam/Makefile.lammps. The latter is copied from an existing Makefile.lammps.* and has settings needed to link C++ (LAMMPS) with Fortran (MEAM library). Typically the two compilers used for LAMMPS and the MEAM library need to be consistent (e.g. both Intel or both GNU compilers). If necessary, you can edit/create a new lib/meam/Makefile.machine file for your system, which should define an EXTRAMAKE variable to specify a corresponding Makefile.lammps.machine file. You can then install/un-install the package and build LAMMPS in the usual manner: make yes-meam make machine :pre make no-meam make machine :pre NOTE: You should test building the MEAM library with both the Intel and GNU compilers to see if a simulation runs faster with one versus the other on your system. [Supporting info:] src/MEAM: filenames -> commands src/meam/README lib/meam/README "pair_style meam"_pair_meam.html examples/meam :ul :line MISC package :link(MISC),h4 [Contents:] A variety of compute, fix, pair, dump styles with specialized capabilities that don't align with other packages. Do a directory listing, "ls src/MISC", to see the list of commands. [Install or un-install:] make yes-misc make machine :pre make no-misc make machine :pre [Supporting info:] src/MISC: filenames -> commands "compute ti"_compute_ti.html "fix evaporate"_fix_evaporate.html "fix orient/fcc"_fix_orient.html "fix ttm"_fix_ttm.html "fix thermal/conductivity"_fix_thermal_conductivity.html "fix viscosity"_fix_viscosity.html examples/KAPPA examples/VISCOSITY http://lammps.sandia.gov/pictures.html#ttm http://lammps.sandia.gov/movies.html#evaporation :ul :line MOLECULE package :link(MOLECULE),h4 [Contents:] A large number of atom, pair, bond, angle, dihedral, improper styles that are used to model molecular systems with fixed covalent bonds. The pair styles include the Dreiding (hydrogen-bonding) and CHARMM force fields, and a TIP4P water model. [Install or un-install:] make yes-molecule make machine :pre make no-molecule make machine :pre [Supporting info:] src/MOLECULE: filenames -> commands "atom_style"_atom_style.html "bond_style"_bond_style.html "angle_style"_angle_style.html "dihedral_style"_dihedral_style.html "improper_style"_improper_style.html "pair_style hbond/dreiding/lj"_pair_hbond_dreiding.html "pair_style lj/charmm/coul/charmm"_pair_charmm.html "Section 6.3"_Section_howto.html#howto_3 examples/cmap examples/dreiding examples/micelle, examples/peptide bench/in.chain bench/in.rhodo :ul :line MPIIO package :link(MPIIO),h4 [Contents:] Support for parallel output/input of dump and restart files via the MPIIO library. It adds "dump styles"_dump.html with a "mpiio" in their style name. Restart files with an ".mpiio" suffix are also written and read in parallel. [Install or un-install:] Note that MPIIO is part of the standard message-passing interface (MPI) library, so you should not need any additional compiler or link settings, beyond what LAMMPS normally uses for MPI on your system. - + make yes-mpiio make machine :pre - + make no-mpiio make machine :pre - + [Supporting info:] src/MPIIO: filenames -> commands "dump"_dump.html "restart"_restart.html "write_restart"_write_restart.html "read_restart"_read_restart.html :ul :line - + MSCG package :link(mscg),h4 [Contents:] A "fix mscg"_fix_mscg.html command which can parameterize a Mulit-Scale Coarse-Graining (MSCG) model using the open-source "MS-CG library"_mscg_home. :link(mscg_home,https://github.com/uchicago-voth/MSCG-release) To use this package you must have the MS-CG library available on your system. [Authors:] The fix was written by Lauren Abbott (Sandia). The MS-CG library was developed by Jacob Wagner in Greg Voth's group at the University of Chicago. [Install or un-install:] Before building LAMMPS with this package, you must first download and build the MS-CG library. Building the MS-CG library and using it from LAMMPS requires a C++11 compatible compiler, and that LAPACK and GSL (GNU Scientific Library) libraries be installed on your machine. See the lib/mscg/README and MSCG/Install files for more details. Assuming these libraries are in place, you can do the download and build of MS-CG manually if you prefer; follow the instructions in lib/mscg/README. You can also do it in one step from the lammps/src dir, using a command like these, which simply invoke the lib/mscg/Install.py script with the specified args: make lib-mscg # print help message make lib-mscg args="-g -b -l" # download and build in default lib/mscg/MSCG-release-master make lib-mscg args="-h . MSCG -g -b -l" # download and build in lib/mscg/MSCG make lib-mscg args="-h ~ MSCG -g -b -l" # download and build in ~/mscg :pre Note that the final -l switch is to create 2 symbolic (soft) links, "includelink" and "liblink", in lib/mscg to point to the MS-CG src dir. When LAMMPS builds it will use these links. You should not need to edit the lib/mscg/Makefile.lammps file. You can then install/un-install the package and build LAMMPS in the usual manner: make yes-mscg make machine :pre make no-mscg make machine :pre [Supporting info:] src/MSCG: filenames -> commands src/MSCG/README lib/mscg/README examples/mscg :ul :line - + OPT package :link(OPT),h4 [Contents:] A handful of pair styles which are optimized for improved CPU performance on single or multiple cores. These include EAM, LJ, CHARMM, and Morse potentials. The styles have an "opt" suffix in their style name. "Section 5.3.5"_accelerate_opt.html gives details of how to build and use this package. Its styles can be invoked at run time via the "-sf opt" or "-suffix opt" "command-line switches"_Section_start.html#start_7. See also the "KOKKOS"_#KOKKOS, "USER-INTEL"_#USER-INTEL, and "USER-OMP"_#USER-OMP packages, which have styles optimized for CPU performance. [Authors:] James Fischer (High Performance Technologies), David Richie, and Vincent Natoli (Stone Ridge Technolgy). [Install or un-install:] make yes-opt make machine :pre make no-opt make machine :pre NOTE: The compile flag "-restrict" must be used to build LAMMPS with the OPT package. It should be added to the CCFLAGS line of your Makefile.machine. See Makefile.opt in src/MAKE/OPTIONS for an example. CCFLAGS: add -restrict :ul [Supporting info:] src/OPT: filenames -> commands "Section 5.3"_Section_accelerate.html#acc_3 "Section 5.3.5"_accelerate_opt.html "Section 2.7 -sf opt"_Section_start.html#start_7 Pair Styles section of "Section 3.5"_Section_commands.html#cmd_5 for pair styles followed by (t) "Benchmarks page"_http://lammps.sandia.gov/bench.html of web site :ul :line PERI package :link(PERI),h4 [Contents:] An atom style, several pair styles which implement different Peridynamics materials models, and several computes which calculate diagnostics. Peridynamics is a a particle-based meshless continuum model. [Authors:] The original package was created by Mike Parks (Sandia). Additional Peridynamics models were added by Rezwanur Rahman and John Foster (UTSA). [Install or un-install:] make yes-peri make machine :pre make no-peri make machine :pre [Supporting info:] src/PERI: filenames -> commands "doc/PDF/PDLammps_overview.pdf"_PDF/PDLammps_overview.pdf "doc/PDF/PDLammps_EPS.pdf"_PDF/PDLammps_EPS.pdf "doc/PDF/PDLammps_VES.pdf"_PDF/PDLammps_VES.pdf "atom_style peri"_atom_style.html "pair_style peri/*"_pair_peri.html "compute damage/atom"_compute_damage_atom.html "compute plasticity/atom"_compute_plasticity_atom.html examples/peri http://lammps.sandia.gov/movies.html#peri :ul :line POEMS package :link(POEMS),h4 [Contents:] A fix that wraps the Parallelizable Open source Efficient Multibody Software (POEMS) library, which is able to simulate the dynamics of articulated body systems. These are systems with multiple rigid bodies (collections of particles) whose motion is coupled by connections at hinge points. [Author:] Rudra Mukherjee (JPL) while at RPI. [Install or un-install:] Before building LAMMPS with this package, you must first build the POEMS library in lib/poems. You can do this manually if you prefer; follow the instructions in lib/poems/README. You can also do it in one step from the lammps/src dir, using a command like these, which simply invoke the lib/poems/Install.py script with the specified args: make lib-poems # print help message make lib-poems args="-m g++" # build with GNU g++ compiler make lib-poems args="-m icc" # build with Intel icc compiler :pre The build should produce two files: lib/poems/libpoems.a and lib/poems/Makefile.lammps. The latter is copied from an existing Makefile.lammps.* and has settings needed to build LAMMPS with the POEMS library (though typically the settings are just blank). If necessary, you can edit/create a new lib/poems/Makefile.machine file for your system, which should define an EXTRAMAKE variable to specify a corresponding Makefile.lammps.machine file. You can then install/un-install the package and build LAMMPS in the usual manner: make yes-poems make machine :pre make no-meam make machine :pre [Supporting info:] src/POEMS: filenames -> commands src/POEMS/README lib/poems/README "fix poems"_fix_poems.html examples/rigid :ul :line PYTHON package :link(PYTHON),h4 [Contents:] A "python"_python.html command which allow you to execute Python code from a LAMMPS input script. The code can be in a separate file or embedded in the input script itself. See "Section 11.2"_Section_python.html#py_2 for an overview of using Python from LAMMPS in this manner and the entire section for other ways to use LAMMPS and Python together. [Install or un-install:] make yes-python make machine :pre make no-python make machine :pre NOTE: Building with the PYTHON package assumes you have a Python shared library available on your system, which needs to be a Python 2 version, 2.6 or later. Python 3 is not yet supported. See the lib/python/README for more details. Note that the build uses the lib/python/Makefile.lammps file in the compile/link process. You should only need to create a new Makefile.lammps.* file (and copy it to Makefile.lammps) if the LAMMPS build fails. [Supporting info:] src/PYTHON: filenames -> commands "Section 11"_Section_python.html lib/python/README examples/python :ul :line QEQ package :link(QEQ),h4 [Contents:] Several fixes for performing charge equilibration (QEq) via different algorithms. These can be used with pair styles that perform QEq as part of their formulation. [Install or un-install:] make yes-qeq make machine :pre make no-qeq make machine :pre [Supporting info:] src/QEQ: filenames -> commands "fix qeq/*"_fix_qeq.html examples/qeq examples/streitz :ul :line REAX package :link(REAX),h4 [Contents:] A pair style which wraps a Fortran library which implements the ReaxFF potential, which is a universal reactive force field. See the "USER-REAXC package"_#USER-REAXC for an alternate implementation in C/C++. Also a "fix reax/bonds"_fix_reax_bonds.html command for monitoring molecules as bonds are created and destroyed. [Author:] Aidan Thompson (Sandia). [Install or un-install:] Before building LAMMPS with this package, you must first build the REAX library in lib/reax. You can do this manually if you prefer; follow the instructions in lib/reax/README. You can also do it in one step from the lammps/src dir, using a command like these, which simply invoke the lib/reax/Install.py script with the specified args: make lib-reax # print help message make lib-reax args="-m gfortran" # build with GNU Fortran compiler make lib-reax args="-m ifort" # build with Intel ifort compiler :pre The build should produce two files: lib/reax/libreax.a and lib/reax/Makefile.lammps. The latter is copied from an existing Makefile.lammps.* and has settings needed to link C++ (LAMMPS) with Fortran (REAX library). Typically the two compilers used for LAMMPS and the REAX library need to be consistent (e.g. both Intel or both GNU compilers). If necessary, you can edit/create a new lib/reax/Makefile.machine file for your system, which should define an EXTRAMAKE variable to specify a corresponding Makefile.lammps.machine file. You can then install/un-install the package and build LAMMPS in the usual manner: make yes-reax make machine :pre make no-reax make machine :pre [Supporting info:] src/REAX: filenames -> commands lib/reax/README "pair_style reax"_pair_reax.html "fix reax/bonds"_fix_reax_bonds.html examples/reax :ul :line REPLICA package :link(REPLICA),h4 [Contents:] A collection of multi-replica methods which can be used when running multiple LAMMPS simulations (replicas). See "Section 6.5"_Section_howto.html#howto_5 for an overview of how to run multi-replica simulations in LAMMPS. Methods in the package include nudged elastic band (NEB), parallel replica dynamics (PRD), temperature accelerated dynamics (TAD), parallel tempering, and a verlet/split algorithm for performing long-range Coulombics on one set of processors, and the remainder of the force field calcalation on another set. [Install or un-install:] make yes-replica make machine :pre make no-replica make machine :pre [Supporting info:] src/REPLICA: filenames -> commands "Section 6.5"_Section_howto.html#howto_5 "neb"_neb.html "prd"_prd.html "tad"_tad.html "temper"_temper.html, "run_style verlet/split"_run_style.html examples/neb examples/prd examples/tad :ul :line RIGID package :link(RIGID),h4 [Contents:] Fixes which enforce rigid constraints on collections of atoms or particles. This includes SHAKE and RATTLE, as well as varous rigid-body integrators for a few large bodies or many small bodies. Also several computes which calculate properties of rigid bodies. To install/build: make yes-rigid make machine :pre To un-install/re-build: make no-rigid make machine :pre [Supporting info:] src/RIGID: filenames -> commands "compute erotate/rigid"_compute_erotate_rigid.html fix shake"_fix_shake.html "fix rattle"_fix_shake.html "fix rigid/*"_fix_rigid.html examples/ASPHERE examples/rigid bench/in.rhodo http://lammps.sandia.gov/movies.html#box http://lammps.sandia.gov/movies.html#star :ul :line SHOCK package :link(SHOCK),h4 [Contents:] Fixes for running impact simulations where a shock-wave passes through a material. [Install or un-install:] make yes-shock make machine :pre make no-shock make machine :pre [Supporting info:] src/SHOCK: filenames -> commands "fix append/atoms"_fix_append_atoms.html "fix msst"_fix_msst.html "fix nphug"_fix_nphug.html "fix wall/piston"_fix_wall_piston.html examples/hugoniostat examples/msst :ul :line SNAP package :link(SNAP),h4 [Contents:] A pair style for the spectral neighbor analysis potential (SNAP). SNAP is methodology for deriving a highly accurate classical potential fit to a large archive of quantum mechanical (DFT) data. Also several computes which analyze attributes of the potential. [Author:] Aidan Thompson (Sandia). [Install or un-install:] make yes-snap make machine :pre make no-snap make machine :pre [Supporting info:] src/SNAP: filenames -> commands "pair snap"_pair_snap.html "compute sna/atom"_compute_sna_atom.html "compute snad/atom"_compute_sna_atom.html "compute snav/atom"_compute_sna_atom.html examples/snap :ul :line SRD package :link(SRD),h4 [Contents:] A pair of fixes which implement the Stochastic Rotation Dynamics (SRD) method for coarse-graining of a solvent, typically around large colloidal particles. To install/build: make yes-srd make machine :pre To un-install/re-build: make no-srd make machine :pre [Supporting info:] src/SRD: filenames -> commands "fix srd"_fix_srd.html "fix wall/srd"_fix_wall_srd.html examples/srd examples/ASPHERE http://lammps.sandia.gov/movies.html#tri http://lammps.sandia.gov/movies.html#line http://lammps.sandia.gov/movies.html#poly :ul :line VORONOI package :link(VORONOI),h4 [Contents:] A compute command which calculates the Voronoi tesselation of a collection of atoms by wrapping the "Voro++ library"_voro_home. This can be used to calculate the local volume or each atoms or its near neighbors. :link(voro_home,http://math.lbl.gov/voro++) To use this package you must have the Voro++ library available on your system. [Author:] Daniel Schwen (INL) while at LANL. The open-source Voro++ library was written by Chris Rycroft (Harvard U) while at UC Berkeley and LBNL. [Install or un-install:] Before building LAMMPS with this package, you must first download and build the Voro++ library. You can do this manually if you prefer; follow the instructions in lib/voronoi/README. You can also do it in one step from the lammps/src dir, using a command like these, which simply invoke the lib/voronoi/Install.py script with the specified args: make lib-voronoi # print help message make lib-voronoi args="-g -b -l" # download and build in default lib/voronoi/voro++-0.4.6 make lib-voronoi args="-h . voro++ -g -b -l" # download and build in lib/voronoi/voro++ make lib-voronoi args="-h ~ voro++ -g -b -l" # download and build in ~/voro++ :pre Note that the final -l switch is to create 2 symbolic (soft) links, "includelink" and "liblink", in lib/voronoi to point to the Voro++ src dir. When LAMMPS builds it will use these links. You should not need to edit the lib/voronoi/Makefile.lammps file. You can then install/un-install the package and build LAMMPS in the usual manner: make yes-voronoi make machine :pre make no-voronoi make machine :pre [Supporting info:] src/VORONOI: filenames -> commands src/VORONOI/README lib/voronoi/README "compute voronoi/atom"_compute_voronoi_atom.html examples/voronoi :ul :line :line USER-ATC package :link(USER-ATC),h4 [Contents:] ATC stands for atoms-to-continuum. This package implements a "fix atc"_fix_atc.html command to either couple molecular dynamics with continuum finite element equations or perform on-the-fly conversion of atomic information to continuum fields. [Authors:] Reese Jones, Jeremy Templeton, Jon Zimmerman (Sandia). [Install or un-install:] - + Before building LAMMPS with this package, you must first build the ATC library in lib/atc. You can do this manually if you prefer; follow the instructions in lib/atc/README. You can also do it in one step from the lammps/src dir, using a command like these, which simply invoke the lib/atc/Install.py script with the specified args: make lib-atc # print help message make lib-atc args="-m g++" # build with GNU g++ compiler make lib-atc args="-m icc" # build with Intel icc compiler :pre The build should produce two files: lib/atc/libatc.a and lib/atc/Makefile.lammps. The latter is copied from an existing Makefile.lammps.* and has settings needed to build LAMMPS with the ATC library. If necessary, you can edit/create a new lib/atc/Makefile.machine file for your system, which should define an EXTRAMAKE variable to specify a corresponding Makefile.lammps.machine file. Note that the Makefile.lammps file has settings for the BLAS and LAPACK linear algebra libraries. As explained in lib/atc/README these can either exist on your system, or you can use the files provided in lib/linalg. In the latter case you also need to build the library in lib/linalg with a command like these: make lib-linalg # print help message make lib-atc args="-m gfortran" # build with GNU Fortran compiler You can then install/un-install the package and build LAMMPS in the usual manner: make yes-user-atc make machine :pre - + make no-user-atc make machine :pre - + [Supporting info:] src/USER-ATC: filenames -> commands src/USER-ATC/README "fix atc"_fix_atc.html examples/USER/atc http://lammps.sandia.gov/pictures.html#atc :ul :line USER-AWPMD package :link(USER-AWPMD),h4 [Contents:] AWPMD stands for Antisymmetrized Wave Packet Molecular Dynamics. This package implements an atom, pair, and fix style which allows electrons to be treated as explicit particles in a classical molecular dynamics model. [Author:] Ilya Valuev (JIHT, Russia). [Install or un-install:] - + Before building LAMMPS with this package, you must first build the AWPMD library in lib/awpmd. You can do this manually if you prefer; follow the instructions in lib/awpmd/README. You can also do it in one step from the lammps/src dir, using a command like these, which simply invoke the lib/awpmd/Install.py script with the specified args: make lib-awpmd # print help message make lib-awpmd args="-m g++" # build with GNU g++ compiler make lib-awpmd args="-m icc" # build with Intel icc compiler :pre The build should produce two files: lib/awpmd/libawpmd.a and lib/awpmd/Makefile.lammps. The latter is copied from an existing Makefile.lammps.* and has settings needed to build LAMMPS with the AWPMD library. If necessary, you can edit/create a new lib/awpmd/Makefile.machine file for your system, which should define an EXTRAMAKE variable to specify a corresponding Makefile.lammps.machine file. Note that the Makefile.lammps file has settings for the BLAS and LAPACK linear algebra libraries. As explained in lib/awpmd/README these can either exist on your system, or you can use the files provided in lib/linalg. In the latter case you also need to build the library in lib/linalg with a command like these: make lib-linalg # print help message make lib-atc args="-m gfortran" # build with GNU Fortran compiler You can then install/un-install the package and build LAMMPS in the usual manner: make yes-user-awpmd make machine :pre - + make no-user-awpmd make machine :pre - + [Supporting info:] src/USER-AWPMD: filenames -> commands src/USER-AWPMD/README "pair awpmd/cut"_pair_awpmd.html examples/USER/awpmd :ul :line USER-CGDNA package :link(USER-CGDNA),h4 [Contents:] Several pair styles, a bond style, and integration fixes for coarse-grained models of single- and double-stranded DNA based on the oxDNA model of Doye, Louis and Ouldridge at the University of Oxford. This includes Langevin-type rigid-body integrators with improved stability. [Author:] Oliver Henrich (University of Strathclyde, Glasgow). [Install or un-install:] - + make yes-user-cgdna make machine :pre - + make no-user-cgdna make machine :pre - + [Supporting info:] src/USER-CGDNA: filenames -> commands /src/USER-CGDNA/README "pair_style oxdna/*"_pair_oxdna.html "pair_style oxdna2/*"_pair_oxdna2.html "bond_style oxdna/*"_bond_oxdna.html "bond_style oxdna2/*"_bond_oxdna.html "fix nve/dotc/langevin"_fix_nve_dotc_langevin.html :ul :line USER-CGSDK package :link(USER-CGSDK),h4 [Contents:] Several pair styles and an angle style which implement the coarse-grained SDK model of Shinoda, DeVane, and Klein which enables simulation of ionic liquids, electrolytes, lipids and charged amino acids. [Author:] Axel Kohlmeyer (Temple U). [Install or un-install:] - + make yes-user-cgsdk make machine :pre - + make no-user-cgsdk make machine :pre - + [Supporting info:] src/USER-CGSDK: filenames -> commands src/USER-CGSDK/README "pair_style lj/sdk/*"_pair_sdk.html "angle_style sdk"_angle_sdk.html examples/USER/cgsdk http://lammps.sandia.gov/pictures.html#cg :ul :line USER-COLVARS package :link(USER-COLVARS),h4 [Contents:] COLVARS stands for collective variables, which can be used to implement various enhanced sampling methods, including Adaptive Biasing Force, Metadynamics, Steered MD, Umbrella Sampling and Restraints. A "fix colvars"_fix_colvars.html command is implemented which wraps a COLVARS library, which implements these methods. simulations. [Authors:] Axel Kohlmeyer (Temple U). The COLVARS library was written by Giacomo Fiorin (ICMS, Temple University, Philadelphia, PA, USA) and Jerome Henin (LISM, CNRS, Marseille, France). [Install or un-install:] - + Before building LAMMPS with this package, you must first build the COLVARS library in lib/colvars. You can do this manually if you prefer; follow the instructions in lib/colvars/README. You can also do it in one step from the lammps/src dir, using a command like these, which simply invoke the lib/colvars/Install.py script with the specified args: make lib-colvars # print help message make lib-colvars args="-m g++" # build with GNU g++ compiler :pre The build should produce two files: lib/colvars/libcolvars.a and lib/colvars/Makefile.lammps. The latter is copied from an existing Makefile.lammps.* and has settings needed to build LAMMPS with the COLVARS library (though typically the settings are just blank). If necessary, you can edit/create a new lib/colvars/Makefile.machine file for your system, which should define an EXTRAMAKE variable to specify a corresponding Makefile.lammps.machine file. You can then install/un-install the package and build LAMMPS in the usual manner: make yes-user-colvars make machine :pre - + make no-user-colvars make machine :pre - + [Supporting info:] src/USER-COLVARS: filenames -> commands "doc/PDF/colvars-refman-lammps.pdf"_PDF/colvars-refman-lammps.pdf src/USER-COLVARS/README lib/colvars/README "fix colvars"_fix_colvars.html examples/USER/colvars :ul :line USER-DIFFRACTION package :link(USER-DIFFRACTION),h4 [Contents:] Two computes and a fix for calculating x-ray and electron diffraction intensities based on kinematic diffraction theory. [Author:] Shawn Coleman while at the U Arkansas. [Install or un-install:] - + make yes-user-diffraction make machine :pre - + make no-user-diffraction make machine :pre - + [Supporting info:] src/USER-DIFFRACTION: filenames -> commands "compute saed"_compute_saed.html "compute xrd"_compute_xrd.html "fix saed/vtk"_fix_saed_vtk.html examples/USER/diffraction :ul :line USER-DPD package :link(USER-DPD),h4 [Contents:] DPD stands for dissipative particle dynamics. This package implements coarse-grained DPD-based models for energetic, reactive molecular crystalline materials. It includes many pair styles specific to these systems, including for reactive DPD, where each particle has internal state for multiple species and a coupled set of chemical reaction ODEs are integrated each timestep. Highly accurate time intergrators for isothermal, isoenergetic, isobaric and isenthalpic conditions are included. These enable long timesteps via the Shardlow splitting algorithm. [Authors:] Jim Larentzos (ARL), Tim Mattox (Engility Corp), and and John Brennan (ARL). [Install or un-install:] - + make yes-user-dpd make machine :pre - + make no-user-dpd make machine :pre - + [Supporting info:] src/USER-DPD: filenames -> commands /src/USER-DPD/README "compute dpd"_compute_dpd.html "compute dpd/atom"_compute_dpd_atom.html "fix eos/cv"_fix_eos_table.html "fix eos/table"_fix_eos_table.html "fix eos/table/rx"_fix_eos_table_rx.html "fix shardlow"_fix_shardlow.html "fix rx"_fix_rx.html "pair table/rx"_pair_table_rx.html "pair dpd/fdt"_pair_dpd_fdt.html "pair dpd/fdt/energy"_pair_dpd_fdt.html "pair exp6/rx"_pair_exp6_rx.html "pair multi/lucy"_pair_multi_lucy.html "pair multi/lucy/rx"_pair_multi_lucy_rx.html examples/USER/dpd :ul :line USER-DRUDE package :link(USER-DRUDE),h4 [Contents:] Fixes, pair styles, and a compute to simulate thermalized Drude oscillators as a model of polarization. See "Section 6.27"_Section_howto.html#howto_27 for an overview of how to use the package. There are auxiliary tools for using this package in tools/drude. [Authors:] Alain Dequidt (U Blaise Pascal Clermont-Ferrand), Julien Devemy (CNRS), and Agilio Padua (U Blaise Pascal). [Install or un-install:] - + make yes-user-drude make machine :pre - + make no-user-drude make machine :pre - + [Supporting info:] src/USER-DRUDE: filenames -> commands "Section 6.27"_Section_howto.html#howto_27 "Section 6.25"_Section_howto.html#howto_25 src/USER-DRUDE/README "fix drude"_fix_drude.html "fix drude/transform/*"_fix_drude_transform.html "compute temp/drude"_compute_temp_drude.html "pair thole"_pair_thole.html "pair lj/cut/thole/long"_pair_thole.html examples/USER/drude tools/drude :ul :line USER-EFF package :link(USER-EFF),h4 [Contents:] EFF stands for electron force field which allows a classical MD code to model electrons as particles of variable radius. This package contains atom, pair, fix and compute styles which implement the eFF as described in A. Jaramillo-Botero, J. Su, Q. An, and W.A. Goddard III, JCC, 2010. The eFF potential was first introduced by Su and Goddard, in 2007. There are auxiliary tools for using this package in tools/eff; see its README file. [Author:] Andres Jaramillo-Botero (CalTech). [Install or un-install:] - + make yes-user-eff make machine :pre - + make no-user-eff make machine :pre - + [Supporting info:] src/USER-EFF: filenames -> commands src/USER-EFF/README "atom_style electron"_atom_style.html "fix nve/eff"_fix_nve_eff.html "fix nvt/eff"_fix_nh_eff.html "fix npt/eff"_fix_nh_eff.html "fix langevin/eff"_fix_langevin_eff.html "compute temp/eff"_compute_temp_eff.html "pair eff/cut"_pair_eff.html "pair eff/inline"_pair_eff.html examples/USER/eff tools/eff/README tools/eff http://lammps.sandia.gov/movies.html#eff :ul :line USER-FEP package :link(USER-FEP),h4 [Contents:] FEP stands for free energy perturbation. This package provides methods for performing FEP simulations by using a "fix adapt/fep"_fix_adapt_fep.html command with soft-core pair potentials, which have a "soft" in their style name. There are auxiliary tools for using this package in tools/fep; see its README file. [Author:] Agilio Padua (Universite Blaise Pascal Clermont-Ferrand) [Install or un-install:] - + make yes-user-fep make machine :pre - + make no-user-fep make machine :pre - + [Supporting info:] src/USER-FEP: filenames -> commands src/USER-FEP/README "fix adapt/fep"_fix_adapt_fep.html "compute fep"_compute_fep.html "pair_style */soft"_pair_lj_soft.html examples/USER/fep tools/fep/README tools/fep :ul :line USER-H5MD package :link(USER-H5MD),h4 [Contents:] H5MD stands for HDF5 for MD. "HDF5"_HDF5 is a portable, binary, self-describing file format, used by many scientific simulations. H5MD is a format for molecular simulations, built on top of HDF5. This package implements a "dump h5md"_dump_h5md.html command to output LAMMPS snapshots in this format. :link(HDF5,http://www.hdfgroup.org/HDF5) To use this package you must have the HDF5 library available on your system. [Author:] Pierre de Buyl (KU Leuven) created both the package and the H5MD format. [Install or un-install:] Note that to follow these steps to compile and link to the CH5MD library, you need the standard HDF5 software package installed on your system, which should include the h5cc compiler and the HDF5 library. Before building LAMMPS with this package, you must first build the CH5MD library in lib/h5md. You can do this manually if you prefer; follow the instructions in lib/h5md/README. You can also do it in one step from the lammps/src dir, using a command like these, which simply invoke the lib/h5md/Install.py script with the specified args: make lib-h5md # print help message make lib-hm5d args="-m h5cc" # build with h5cc compiler :pre The build should produce two files: lib/h5md/libch5md.a and lib/h5md/Makefile.lammps. The latter is copied from an existing Makefile.lammps.* and has settings needed to build LAMMPS with the system HDF5 library. If necessary, you can edit/create a new lib/h5md/Makefile.machine file for your system, which should define an EXTRAMAKE variable to specify a corresponding Makefile.lammps.machine file. You can then install/un-install the package and build LAMMPS in the usual manner: - + make yes-user-h5md make machine :pre - + make no-user-h5md make machine :pre - + [Supporting info:] src/USER-H5MD: filenames -> commands src/USER-H5MD/README lib/h5md/README "dump h5md"_dump_h5md.html :ul :line USER-INTEL package :link(USER-INTEL),h4 [Contents:] Dozens of pair, fix, bond, angle, dihedral, improper, and kspace styles which are optimized for Intel CPUs and KNLs (Knights Landing). All of them have an "intel" in their style name. "Section 5.3.2"_accelerate_intel.html gives details of what hardware and compilers are required on your system, and how to build and use this package. Its styles can be invoked at run time via the "-sf intel" or "-suffix intel" "command-line switches"_Section_start.html#start_7. Also see the "KOKKOS"_#KOKKOS, "OPT"_#OPT, and "USER-OMP"_#USER-OMP packages, which have styles optimized for CPUs and KNLs. You need to have an Intel compiler, version 14 or higher to take full advantage of this package. [Author:] Mike Brown (Intel). [Install or un-install:] For the USER-INTEL package, you have 2 choices when building. You can build with either CPU or KNL support. Each choice requires additional settings in your Makefile.machine for CCFLAGS and LINKFLAGS and optimized malloc libraries. See the src/MAKE/OPTIONS/Makefile.intel_cpu and src/MAKE/OPTIONS/Makefile.knl files for examples. For CPUs: OPTFLAGS = -xHost -O2 -fp-model fast=2 -no-prec-div -qoverride-limits CCFLAGS = -g -qopenmp -DLAMMPS_MEMALIGN=64 -no-offload \ -fno-alias -ansi-alias -restrict $(OPTFLAGS) LINKFLAGS = -g -qopenmp $(OPTFLAGS) LIB = -ltbbmalloc -ltbbmalloc_proxy For KNLs: OPTFLAGS = -xMIC-AVX512 -O2 -fp-model fast=2 -no-prec-div -qoverride-limits CCFLAGS = -g -qopenmp -DLAMMPS_MEMALIGN=64 -no-offload \ -fno-alias -ansi-alias -restrict $(OPTFLAGS) LINKFLAGS = -g -qopenmp $(OPTFLAGS) LIB = -ltbbmalloc Once you have an appropriate Makefile.machine, you can install/un-install the package and build LAMMPS in the usual manner. Note that you cannot build one executable to run on multiple hardware targets (Intel CPUs or KNL). You need to build LAMMPS once for each hardware target, to produce a separate executable. You should also typically install the USER-OMP package, as it can be used in tandem with the USER-INTEL package to good effect, as explained in "Section 5.3.2"_accelerate_intel.html. make yes-user-intel yes-user-omp make machine :pre - + make no-user-intel no-user-omp make machine :pre [Supporting info:] src/USER-INTEL: filenames -> commands src/USER-INTEL/README "Section 5.3"_Section_accelerate.html#acc_3 "Section 5.3.2"_accelerate_gpu.html "Section 2.7 -sf intel"_Section_start.html#start_7 "Section 2.7 -pk intel"_Section_start.html#start_7 "package intel"_package.html Styles sections of "Section 3.5"_Section_commands.html#cmd_5 for styles followed by (i) src/USER-INTEL/TEST "Benchmarks page"_http://lammps.sandia.gov/bench.html of web site :ul :line USER-LB package :link(USER-LB),h4 [Contents:] Fixes which implement a background Lattice-Boltzmann (LB) fluid, which can be used to model MD particles influenced by hydrodynamic forces. [Authors:] Frances Mackay and Colin Denniston (University of Western Ontario). [Install or un-install:] - + make yes-user-lb make machine :pre - + make no-user-lb make machine :pre - + [Supporting info:] src/USER-LB: filenames -> commands src/USER-LB/README "fix lb/fluid"_fix_lb_fluid.html "fix lb/momentum"_fix_lb_momentum.html "fix lb/viscous"_fix_lb_viscous.html examples/USER/lb :ul :line USER-MGPT package :link(USER-MGPT),h4 [Contents:] A pair style which provides a fast implementation of the quantum-based MGPT multi-ion potentials. The MGPT or model GPT method derives from first-principles DFT-based generalized pseudopotential theory (GPT) through a series of systematic approximations valid for mid-period transition metals with nearly half-filled d bands. The MGPT method was originally developed by John Moriarty at LLNL. The pair style in this package calculates forces and energies using an optimized matrix-MGPT algorithm due to Tomas Oppelstrup at LLNL. [Authors:] Tomas Oppelstrup and John Moriarty (LLNL). [Install or un-install:] - + make yes-user-mgpt make machine :pre - + make no-user-mgpt make machine :pre - + [Supporting info:] src/USER-MGPT: filenames -> commands src/USER-MGPT/README "pair_style mgpt"_pair_mgpt.html examples/USER/mgpt :ul :line USER-MISC package :link(USER-MISC),h4 [Contents:] A potpourri of (mostly) unrelated features contributed to LAMMPS by users. Each feature is a single fix, compute, pair, bond, angle, dihedral, improper, or command style. [Authors:] The author for each style in the package is listed in the src/USER-MISC/README file. [Install or un-install:] - + make yes-user-misc make machine :pre - + make no-user-misc make machine :pre - + [Supporting info:] src/USER-MISC: filenames -> commands src/USER-MISC/README one doc page per individual command listed in src/USER-MISC/README examples/USER/misc :ul :line USER-MANIFOLD package :link(USER-MANIFOLD),h4 [Contents:] Several fixes and a "manifold" class which enable simulations of particles constrained to a manifold (a 2D surface within the 3D simulation box). This is done by applying the RATTLE constraint algorithm to formulate single-particle constraint functions g(xi,yi,zi) = 0 and their derivative (i.e. the normal of the manifold) n = grad(g). [Author:] Stefan Paquay (until 2017: Eindhoven University of Technology (TU/e), The Netherlands; since 2017: Brandeis University, Waltham, MA, USA) [Install or un-install:] - + make yes-user-manifold make machine :pre - + make no-user-manifold make machine :pre - + [Supporting info:] src/USER-MANIFOLD: filenames -> commands src/USER-MANIFOLD/README "doc/manifolds"_manifolds.html "fix manifoldforce"_fix_manifoldforce.html "fix nve/manifold/rattle"_fix_nve_manifold_rattle.html "fix nvt/manifold/rattle"_fix_nvt_manifold_rattle.html examples/USER/manifold http://lammps.sandia.gov/movies.html#manifold :ul :line USER-MOLFILE package :link(USER-MOLFILE),h4 [Contents:] A "dump molfile"_dump_molfile.html command which uses molfile plugins that are bundled with the "VMD"_vmd_home molecular visualization and analysis program, to enable LAMMPS to dump snapshots in formats compatible with various molecular simulation tools. :link(vmd_home,http://www.ks.uiuc.edu/Research/vmd) To use this package you must have the desired VMD plugins available on your system. Note that this package only provides the interface code, not the plugins themselves, which will be accessed when requesting a specific plugin via the "dump molfile"_dump_molfile.html command. Plugins can be obtained from a VMD installation which has to match the platform that you are using to compile LAMMPS for. By adding plugins to VMD, support for new file formats can be added to LAMMPS (or VMD or other programs that use them) without having to recompile the application itself. More information about the VMD molfile plugins can be found at "http://www.ks.uiuc.edu/Research/vmd/plugins/molfile"_http://www.ks.uiuc.edu/Research/vmd/plugins/molfile. [Author:] Axel Kohlmeyer (Temple U). [Install or un-install:] - + Note that the lib/molfile/Makefile.lammps file has a setting for a dynamic loading library libdl.a that should is typically present on all systems, which is required for LAMMPS to link with this package. If the setting is not valid for your system, you will need to edit the Makefile.lammps file. See lib/molfile/README and lib/molfile/Makefile.lammps for details. make yes-user-molfile make machine :pre - + make no-user-molfile make machine :pre - + [Supporting info:] src/USER-MOLFILE: filenames -> commands src/USER-MOLFILE/README lib/molfile/README "dump molfile"_dump_molfile.html :ul :line USER-NETCDF package :link(USER-NETCDF),h4 [Contents:] Dump styles for writing NetCDF formatted dump files. NetCDF is a portable, binary, self-describing file format developed on top of HDF5. The file contents follow the AMBER NetCDF trajectory conventions (http://ambermd.org/netcdf/nctraj.xhtml), but include extensions. To use this package you must have the NetCDF library available on your system. Note that NetCDF files can be directly visualized with the following tools: "Ovito"_ovito (Ovito supports the AMBER convention and the extensions mentioned above) "VMD"_vmd_home "AtomEye"_atomeye (the libAtoms version of AtomEye contains a NetCDF reader not present in the standard distribution) :ul :link(ovito,http://www.ovito.org) :link(atomeye,http://www.libatoms.org) [Author:] Lars Pastewka (Karlsruhe Institute of Technology). [Install or un-install:] - + Note that to follow these steps, you need the standard NetCDF software package installed on your system. The lib/netcdf/Makefile.lammps file has settings for NetCDF include and library files that LAMMPS needs to compile and linkk with this package. If the settings are not valid for your system, you will need to edit the Makefile.lammps file. See lib/netcdf/README for details. make yes-user-netcdf make machine :pre - + make no-user-netcdf make machine :pre [Supporting info:] src/USER-NETCDF: filenames -> commands src/USER-NETCDF/README lib/netcdf/README "dump netcdf"_dump_netcdf.html :ul :line USER-OMP package :link(USER-OMP),h4 [Contents:] Hundreds of pair, fix, compute, bond, angle, dihedral, improper, and kspace styles which are altered to enable threading on many-core CPUs via OpenMP directives. All of them have an "omp" in their style name. "Section 5.3.4"_accelerate_omp.html gives details of what hardware and compilers are required on your system, and how to build and use this package. Its styles can be invoked at run time via the "-sf omp" or "-suffix omp" "command-line switches"_Section_start.html#start_7. Also see the "KOKKOS"_#KOKKOS, "OPT"_#OPT, and "USER-INTEL"_#USER-INTEL packages, which have styles optimized for CPUs. [Author:] Axel Kohlmeyer (Temple U). NOTE: The compile flags "-restrict" and "-fopenmp" must be used to build LAMMPS with the USER-OMP package, as well as the link flag "-fopenmp". They should be added to the CCFLAGS and LINKFLAGS lines of your Makefile.machine. See src/MAKE/OPTIONS/Makefile.omp for an example. Once you have an appropriate Makefile.machine, you can install/un-install the package and build LAMMPS in the usual manner: [Install or un-install:] - + make yes-user-omp make machine :pre - + make no-user-omp make machine :pre CCFLAGS: add -fopenmp and -restrict LINKFLAGS: add -fopenmp :ul [Supporting info:] src/USER-OMP: filenames -> commands src/USER-OMP/README "Section 5.3"_Section_accelerate.html#acc_3 "Section 5.3.4"_accelerate_omp.html "Section 2.7 -sf omp"_Section_start.html#start_7 "Section 2.7 -pk omp"_Section_start.html#start_7 "package omp"_package.html Styles sections of "Section 3.5"_Section_commands.html#cmd_5 for styles followed by (o) "Benchmarks page"_http://lammps.sandia.gov/bench.html of web site :ul :line USER-PHONON package :link(USER-PHONON),h4 [Contents:] A "fix phonon"_fix_phonon.html command that calculates dynamical matrices, which can then be used to compute phonon dispersion relations, directly from molecular dynamics simulations. [Author:] Ling-Ti Kong (Shanghai Jiao Tong University). [Install or un-install:] - + make yes-user-phonon make machine :pre - + make no-user-phonon make machine :pre - + [Supporting info:] src/USER-PHONON: filenames -> commands src/USER-PHONON/README "fix phonon"_fix_phonon.html examples/USER/phonon :ul :line USER-QMMM package :link(USER-QMMM),h4 [Contents:] A "fix qmmm"_fix_qmmm.html command which allows LAMMPS to be used in a QM/MM simulation, currently only in combination with the "Quantum -ESPRESSO"_espresso package. +ESPRESSO"_espresso package. :link(espresso,http://www.quantum-espresso.org) To use this package you must have Quantum ESPRESSO available on your system. The current implementation only supports an ONIOM style mechanical coupling to the Quantum ESPRESSO plane wave DFT package. Electrostatic coupling is in preparation and the interface has been written in a manner that coupling to other QM codes should be possible without changes to LAMMPS itself. [Author:] Axel Kohlmeyer (Temple U). [Install or un-install:] Before building LAMMPS with this package, you must first build the QMMM library in lib/qmmm. You can do this manually if you prefer; follow the first two steps explained in lib/colvars/README. You can also do it in one step from the lammps/src dir, using a command like these, which simply invoke the lib/colvars/Install.py script with the specified args: make lib-qmmm # print help message make lib-qmmm args="-m gfortran" # build with GNU Fortran compiler :pre The build should produce two files: lib/qmmm/libqmmm.a and lib/qmmm/Makefile.lammps. The latter is copied from an existing Makefile.lammps.* and has settings needed to build LAMMPS with the QMMM library (though typically the settings are just blank). If necessary, you can edit/create a new lib/qmmm/Makefile.machine file for your system, which should define an EXTRAMAKE variable to specify a corresponding Makefile.lammps.machine file. You can then install/un-install the package and build LAMMPS in the usual manner: make yes-user-qmmm make machine :pre - + make no-user-qmmm make machine :pre NOTE: The LAMMPS executable these steps produce is not yet functional for a QM/MM simulation. You must also build Quantum ESPRESSO and create a new executable which links LAMMPS and Quanutm ESPRESSO together. These are steps 3 and 4 described in the lib/qmmm/README file. - + [Supporting info:] src/USER-QMMM: filenames -> commands src/USER-QMMM/README lib/qmmm/README "fix phonon"_fix_phonon.html lib/qmmm/example-ec/README lib/qmmm/example-mc/README :ul :line USER-QTB package :link(USER-QTB),h4 [Contents:] Two fixes which provide a self-consistent quantum treatment of vibrational modes in a classical molecular dynamics simulation. By coupling the MD simulation to a colored thermostat, it introduces zero point energy into the system, altering the energy power spectrum and the heat capacity to account for their quantum nature. This is useful when modeling systems at temperatures lower than their classical limits or when temperatures ramp across the classical limits in a simulation. [Author:] Yuan Shen (Stanford U). [Install or un-install:] - + make yes-user-qtb make machine :pre - + make no-user-qtb make machine :pre - + [Supporting info:] src/USER-QTB: filenames -> commands src/USER-QTB/README "fix qtb"_fix_qtb.html "fix qbmsst"_fix_qbmsst.html examples/USER/qtb :ul :line USER-QUIP package :link(USER-QUIP),h4 [Contents:] A "pair_style quip"_pair_quip.html command which wraps the "QUIP libAtoms library"_quip, which includes a variety of interatomic potentials, including Gaussian Approximation Potential (GAP) models developed by the Cambridge University group. :link(quip,https://github.com/libAtoms/QUIP) To use this package you must have the QUIP libAatoms library available on your system. [Author:] Albert Bartok (Cambridge University) [Install or un-install:] Note that to follow these steps to compile and link to the QUIP library, you must first download and build QUIP on your systems. It can be obtained from GitHub. See step 1 and step 1.1 in the lib/quip/README file for details on how to do this. Note that it requires setting two environment variables, QUIP_ROOT and QUIP_ARCH, which will be accessed by the lib/quip/Makefile.lammps file which is used when you compile and link LAMMPS with this package. You should only need to edit this file if the LAMMPS build can not use its settings to successfully build on your system. You can then install/un-install the package and build LAMMPS in the usual manner: make yes-user-quip make machine :pre - + make no-user-quip make machine :pre - + [Supporting info:] src/USER-QUIP: filenames -> commands src/USER-QUIP/README "pair_style quip"_pair_quip.html examples/USER/quip :ul :line USER-REAXC package :link(USER-REAXC),h4 [Contents:] A pair style which implements the ReaxFF potential in C/C++ (in contrast to the "REAX package"_#REAX and its Fortran library). ReaxFF is universal reactive force field. See the src/USER-REAXC/README file for more info on differences between the two packages. Also two fixes for monitoring molecules as bonds are created and destroyed. [Author:] Hasan Metin Aktulga (MSU) while at Purdue University. [Install or un-install:] - + make yes-user-reaxc make machine :pre - + make no-user-reaxc make machine :pre - + [Supporting info:] src/USER-REAXC: filenames -> commands src/USER-REAXC/README "pair_style reax/c"_pair_reaxc.html "fix reax/c/bonds"_fix_reax_bonds.html "fix reax/c/species"_fix_reaxc_species.html examples/reax :ul :line USER-SMD package :link(USER-SMD),h4 [Contents:] An atom style, fixes, computes, and several pair styles which implements smoothed Mach dynamics (SMD) for solids, which is a model related to smoothed particle hydrodynamics (SPH) for liquids (see the "USER-SPH package"_#USER-SPH). This package solves solids mechanics problems via a state of the art stabilized meshless method with hourglass control. It can specify hydrostatic interactions independently from material strength models, i.e. pressure and deviatoric stresses are separated. It provides many material models (Johnson-Cook, plasticity with hardening, Mie-Grueneisen, Polynomial EOS) and allows new material models to be added. It implements rigid boundary conditions (walls) which can be specified as surface geometries from *.STL files. [Author:] Georg Ganzenmuller (Fraunhofer-Institute for High-Speed Dynamics, Ernst Mach Institute, Germany). [Install or un-install:] Before building LAMMPS with this package, you must first download the Eigen library. Eigen is a template library, so you do not need to build it, just download it. You can do this manually if you prefer; follow the instructions in lib/smd/README. You can also do it in one step from the lammps/src dir, using a command like these, which simply invoke the lib/smd/Install.py script with the specified args: make lib-smd # print help message make lib-smd args="-g -l" # download in default lib/smd/eigen-eigen-* make lib-smd args="-h . eigen -g -l" # download in lib/smd/eigen make lib-smd args="-h ~ eigen -g -l" # download and build in ~/eigen :pre Note that the final -l switch is to create a symbolic (soft) link named "includelink" in lib/smd to point to the Eigen dir. When LAMMPS builds it will use this link. You should not need to edit the lib/smd/Makefile.lammps file. You can then install/un-install the package and build LAMMPS in the usual manner: make yes-user-smd make machine :pre - + make no-user-smd make machine :pre - + [Supporting info:] src/USER-SMD: filenames -> commands src/USER-SMD/README doc/PDF/SMD_LAMMPS_userguide.pdf examples/USER/smd http://lammps.sandia.gov/movies.html#smd :ul :line USER-SMTBQ package :link(USER-SMTBQ),h4 [Contents:] A pair style which implements a Second Moment Tight Binding model with QEq charge equilibration (SMTBQ) potential for the description of ionocovalent bonds in oxides. [Authors:] Nicolas Salles, Emile Maras, Olivier Politano, and Robert Tetot (LAAS-CNRS, France). [Install or un-install:] - + make yes-user-smtbq make machine :pre - + make no-user-smtbq make machine :pre - + [Supporting info:] src/USER-SMTBQ: filenames -> commands src/USER-SMTBQ/README "pair_style smtbq"_pair_smtbq.html examples/USER/smtbq :ul :line USER-SPH package :link(USER-SPH),h4 [Contents:] An atom style, fixes, computes, and several pair styles which implements smoothed particle hydrodynamics (SPH) for liquids. See the related "USER-SMD package"_#USER-SMD package for smooth Mach dynamics (SMD) for solids. This package contains ideal gas, Lennard-Jones equation of states, Tait, and full support for complete (i.e. internal-energy dependent) equations of state. It allows for plain or Monaghans XSPH integration of the equations of motion. It has options for density continuity or density summation to propagate the density field. It has "set"_set.html command options to set the internal energy and density of particles from the input script and allows the same quantities to be output with thermodynamic output or to dump files via the "compute property/atom"_compute_property_atom.html command. [Author:] Georg Ganzenmuller (Fraunhofer-Institute for High-Speed Dynamics, Ernst Mach Institute, Germany). [Install or un-install:] - + make yes-user-sph make machine :pre - + make no-user-sph make machine :pre - + [Supporting info:] src/USER-SPH: filenames -> commands src/USER-SPH/README doc/PDF/SPH_LAMMPS_userguide.pdf examples/USER/sph http://lammps.sandia.gov/movies.html#sph :ul :line USER-TALLY package :link(USER-TALLY),h4 [Contents:] Several compute styles that can be called when pairwise interactions are calculated to tally information (forces, heat flux, energy, stress, etc) about individual interactions. [Author:] Axel Kohlmeyer (Temple U). [Install or un-install:] - + make yes-user-tally make machine :pre - + make no-user-tally make machine :pre - + [Supporting info:] src/USER-TALLY: filenames -> commands src/USER-TALLY/README "compute */tally"_compute_tally.html examples/USER/tally :ul :line USER-VTK package :link(USER-VTK),h4 [Contents:] A "dump vtk"_dump_vtk.html command which outputs snapshot info in the "VTK format"_vtk, enabling visualization by "Paraview"_paraview or other visuzlization packages. :link(vtk,http://www.vtk.org) :link(paraview,http://www.paraview.org) To use this package you must have VTK library available on your system. [Authors:] Richard Berger (JKU) and Daniel Queteschiner (DCS Computing). [Install or un-install:] - + The lib/vtk/Makefile.lammps file has settings for accessing VTK files and its library, which are required for LAMMPS to build and link with this package. If the settings are not valid for your system, check if one of the other lib/vtk/Makefile.lammps.* files is compatible and copy it to Makefile.lammps. If none of the provided files work, you will need to edit the Makefile.lammps file. You can then install/un-install the package and build LAMMPS in the usual manner: make yes-user-vtk make machine :pre - + make no-user-vtk make machine :pre - + [Supporting info:] src/USER-VTK: filenames -> commands src/USER-VTK/README lib/vtk/README "dump vtk"_dump_vtk.html :ul diff --git a/doc/src/Section_python.txt b/doc/src/Section_python.txt index 718e9e229..1e67fca32 100644 --- a/doc/src/Section_python.txt +++ b/doc/src/Section_python.txt @@ -1,866 +1,866 @@ "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 three 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, the low-level Python interface can be used indirectly through the PyLammps and IPyLammps wrapper classes in Python. These wrappers try to simplify the usage of LAMMPS in Python by providing an object-based interface to common LAMMPS functionality. It also reduces the amount of code necessary to parameterize LAMMPS scripts through Python and makes variables and computes directly accessible. See "PyLammps interface"_#py_9 for more details. Third, 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 use these three approaches. 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 11.9 "PyLammps interface"_#py_9 :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 included 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 LAMMPS has several commands which can be used to invoke Python code directly from an input script: "python"_python.html "variable python"_variable.html "fix python"_fix_python.html "pair_style python"_pair_python.html :ul The "python"_python.html command which can be used 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. The "fix python"_fix_python.html command can execute Python code at selected timesteps during a simulation run. The "pair_style python"_pair_python command allows you to define pairwise potentials as python code which encodes a single pairwise interaction. This is useful for rapid-developement and debugging of a new potential. To use any of these commands, 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 preceding 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 successfully 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 successfully 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, and which are described in "Section 6.19"_Section_howto.html#howto_19 of the manual. 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 lmp.commands_list(cmdlist) # invoke commands in cmdlist = ["run 10", "run 20"] lmp.commands_string(multicmd) # invoke commands in multicmd = "run 10\nrun 20" xlo = lmp.extract_global(name,type) # extract a global quantity # name = "boxxlo", "nlocal", etc # 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 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 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 flag = lmp.set_variable(name,value) # set existing named string-style variable to value, flag = 0 if successful value = lmp.get_thermo(name) # return current value of a thermo keyword natoms = lmp.get_natoms() # total # of atoms as int data = lmp.gather_atoms(name,type,count) # return per-atom property 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 per-atom property to 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 subsequent calls to the LAMMPS library. Additional arguments to lammps() 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(), command(), commands_list(), commands_string() methods allow an input script, a single command, or multiple 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 if the property you want is not listed. 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 calculated 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 allows any per-atom property (coordinates, velocities, etc) to be extracted from LAMMPS. It returns a ctypes vector of ints or doubles as specified by type, of length count*natoms, for the named property for all atoms in the simulation. The data is ordered by count and then by atom ID. See the extract() method in the src/atom.cpp file for a list of valid names. Again, new names could easily be added if the property you want is missing. 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. A special treatment is applied for image flags stored in the "image" property. All three image flags are stored in a packed format in a single integer, so count would be 1 to retrieve that integer, however also a count value of 3 can be used and then the image flags will be unpacked into 3 individual integers, ordered -in a similar fashion as coordinates. +in a similar fashion as coordinates. 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 allows any per-atom property (coordinates, velocities, etc) to be inserted into LAMMPS, overwriting the current property. It takes a vector of ints or doubles as specified by type, of length count*natoms, for the named property for all atoms in the simulation. The data should be ordered by count and then by atom ID. See the extract() method in the src/atom.cpp file for a list of valid names. Again, new names could easily be added if the property you want is missing. 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. Similar as for gather_atoms() a special treatment is applied for image flags, which can be provided in packed (count = 1) or unpacked (count = 3) format and in the latter case, they will be packed before applied to atoms. 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_atoms("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 temperature 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) 11.9 PyLammps interface :link(py_9),h4 Please see the "PyLammps Tutorial"_tutorial_pylammps.html. diff --git a/doc/src/accelerate_intel.txt b/doc/src/accelerate_intel.txt index ed9e4ae83..f5bd66aeb 100644 --- a/doc/src/accelerate_intel.txt +++ b/doc/src/accelerate_intel.txt @@ -1,511 +1,511 @@ "Previous Section"_Section_packages.html - "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 "Return to Section accelerate overview"_Section_accelerate.html 5.3.2 USER-INTEL package :h5 The USER-INTEL package is maintained by Mike Brown at Intel Corporation. It provides two methods for accelerating simulations, depending on the hardware you have. The first is acceleration on Intel CPUs by running in single, mixed, or double precision with vectorization. The second is acceleration on Intel Xeon Phi coprocessors via offloading neighbor list and non-bonded force calculations to the Phi. The same C++ code is used in both cases. When offloading to a coprocessor from a CPU, the same routine is run twice, once on the CPU and once with an offload flag. This allows LAMMPS to run on the CPU cores and coprocessor cores simultaneously. [Currently Available USER-INTEL Styles:] Angle Styles: charmm, harmonic :ulb,l Bond Styles: fene, harmonic :l Dihedral Styles: charmm, harmonic, opls :l Fixes: nve, npt, nvt, nvt/sllod :l Improper Styles: cvff, harmonic :l Pair Styles: buck/coul/cut, buck/coul/long, buck, eam, gayberne, charmm/coul/long, lj/cut, lj/cut/coul/long, lj/long/coul/long, sw, tersoff :l K-Space Styles: pppm, pppm/disp :l :ule [Speed-ups to expect:] The speedups will depend on your simulation, the hardware, which styles are used, the number of atoms, and the floating-point precision mode. Performance improvements are shown compared to LAMMPS {without using other acceleration packages} as these are under active development (and subject to performance changes). The measurements were performed using the input files available in -the src/USER-INTEL/TEST directory with the provided run script. -These are scalable in size; the results given are with 512K -particles (524K for Liquid Crystal). Most of the simulations are +the src/USER-INTEL/TEST directory with the provided run script. +These are scalable in size; the results given are with 512K +particles (524K for Liquid Crystal). Most of the simulations are standard LAMMPS benchmarks (indicated by the filename extension in -parenthesis) with modifications to the run length and to add a +parenthesis) with modifications to the run length and to add a warmup run (for use with offload benchmarks). :c,image(JPG/user_intel.png) Results are speedups obtained on Intel Xeon E5-2697v4 processors (code-named Broadwell) and Intel Xeon Phi 7250 processors (code-named Knights Landing) with "June 2017" LAMMPS built with Intel Parallel Studio 2017 update 2. Results are with 1 MPI task per physical core. See {src/USER-INTEL/TEST/README} for the raw simulation rates and instructions to reproduce. :line [Accuracy and order of operations:] In most molecular dynamics software, parallelization parameters (# of MPI, OpenMP, and vectorization) can change the results due -to changing the order of operations with finite-precision +to changing the order of operations with finite-precision calculations. The USER-INTEL package is deterministic. This means that the results should be reproducible from run to run with the -{same} parallel configurations and when using determinstic +{same} parallel configurations and when using determinstic libraries or library settings (MPI, OpenMP, FFT). However, there are differences in the USER-INTEL package that can change the order of operations compared to LAMMPS without acceleration: Neighbor lists can be created in a different order :ulb,l Bins used for sorting atoms can be oriented differently :l -The default stencil order for PPPM is 7. By default, LAMMPS will -calculate other PPPM parameters to fit the desired acuracy with +The default stencil order for PPPM is 7. By default, LAMMPS will +calculate other PPPM parameters to fit the desired acuracy with this order :l The {newton} setting applies to all atoms, not just atoms shared between MPI tasks :l Vectorization can change the order for adding pairwise forces :l :ule -The precision mode (described below) used with the USER-INTEL -package can change the {accuracy} of the calculations. For the -default {mixed} precision option, calculations between pairs or -triplets of atoms are performed in single precision, intended to +The precision mode (described below) used with the USER-INTEL +package can change the {accuracy} of the calculations. For the +default {mixed} precision option, calculations between pairs or +triplets of atoms are performed in single precision, intended to be within the inherent error of MD simulations. All accumulation -is performed in double precision to prevent the error from growing +is performed in double precision to prevent the error from growing with the number of atoms in the simulation. {Single} precision mode should not be used without appropriate validation. :line [Quick Start for Experienced Users:] LAMMPS should be built with the USER-INTEL package installed. Simulations should be run with 1 MPI task per physical {core}, not {hardware thread}. Edit src/MAKE/OPTIONS/Makefile.intel_cpu_intelmpi as necessary. :ulb,l Set the environment variable KMP_BLOCKTIME=0 :l "-pk intel 0 omp $t -sf intel" added to LAMMPS command-line :l $t should be 2 for Intel Xeon CPUs and 2 or 4 for Intel Xeon Phi :l For some of the simple 2-body potentials without long-range electrostatics, performance and scalability can be better with the "newton off" setting added to the input script :l -If using {kspace_style pppm} in the input script, add +If using {kspace_style pppm} in the input script, add "kspace_modify diff ad" for better performance :l :ule For Intel Xeon Phi CPUs: Runs should be performed using MCDRAM. :ulb,l :ule -For simulations using {kspace_style pppm} on Intel CPUs +For simulations using {kspace_style pppm} on Intel CPUs supporting AVX-512: Add "kspace_modify diff ad" to the input script :ulb,l -The command-line option should be changed to -"-pk intel 0 omp $r lrt yes -sf intel" where $r is the number of +The command-line option should be changed to +"-pk intel 0 omp $r lrt yes -sf intel" where $r is the number of threads minus 1. :l Do not use thread affinity (set KMP_AFFINITY=none) :l The "newton off" setting may provide better scalability :l :ule For Intel Xeon Phi coprocessors (Offload): Edit src/MAKE/OPTIONS/Makefile.intel_coprocessor as necessary :ulb,l "-pk intel N omp 1" added to command-line where N is the number of coprocessors per node. :l :ule :line [Required hardware/software:] In order to use offload to coprocessors, an Intel Xeon Phi coprocessor and an Intel compiler are required. For this, the recommended version of the Intel compiler is 14.0.1.106 or versions 15.0.2.044 and higher. Although any compiler can be used with the USER-INTEL package, currently, vectorization directives are disabled by default when not using Intel compilers due to lack of standard support and observations of decreased performance. The OpenMP standard now supports directives for vectorization and we plan to transition the code to this standard once it is available in most compilers. We expect this to allow improved performance and support with other compilers. For Intel Xeon Phi x200 series processors (code-named Knights Landing), there are multiple configuration options for the hardware. For best performance, we recommend that the MCDRAM is configured in "Flat" mode and with the cluster mode set to "Quadrant" or "SNC4". "Cache" mode can also be used, although the performance might be slightly lower. [Notes about Simultaneous Multithreading:] Modern CPUs often support Simultaneous Multithreading (SMT). On Intel processors, this is called Hyper-Threading (HT) technology. SMT is hardware support for running multiple threads efficiently on a single core. {Hardware threads} or {logical cores} are often used to refer to the number of threads that are supported in hardware. For example, the Intel Xeon E5-2697v4 processor is described as having 36 cores and 72 threads. This means that 36 MPI processes or OpenMP threads can run simultaneously on separate cores, but that up to 72 MPI processes or OpenMP threads can be running on the CPU without costly operating system context switches. Molecular dynamics simulations will often run faster when making use of SMT. If a thread becomes stalled, for example because it is waiting on data that has not yet arrived from memory, another thread can start running so that the CPU pipeline is still being used efficiently. Although benefits can be seen by launching a MPI task for every hardware thread, for multinode simulations, we recommend that OpenMP threads are used for SMT instead, either with the USER-INTEL package, "USER-OMP package"_accelerate_omp.html, or "KOKKOS package"_accelerate_kokkos.html. In the example above, up to 36X speedups can be observed by using all 36 physical cores with LAMMPS. By using all 72 hardware threads, an additional 10-30% performance gain can be achieved. The BIOS on many platforms allows SMT to be disabled, however, we do not recommend this on modern processors as there is little to no benefit for any software package in most cases. The operating system will report every hardware thread as a separate core allowing one to determine the number of hardware threads available. On Linux systems, this information can normally be obtained with: cat /proc/cpuinfo :pre [Building LAMMPS with the USER-INTEL package:] NOTE: See the src/USER-INTEL/README file for additional flags that might be needed for best performance on Intel server processors code-named "Skylake". The USER-INTEL package must be installed into the source directory: make yes-user-intel :pre Several example Makefiles for building with the Intel compiler are included with LAMMPS in the src/MAKE/OPTIONS/ directory: Makefile.intel_cpu_intelmpi # Intel Compiler, Intel MPI, No Offload Makefile.knl # Intel Compiler, Intel MPI, No Offload Makefile.intel_cpu_mpich # Intel Compiler, MPICH, No Offload Makefile.intel_cpu_openpmi # Intel Compiler, OpenMPI, No Offload Makefile.intel_coprocessor # Intel Compiler, Intel MPI, Offload :pre Makefile.knl is identical to Makefile.intel_cpu_intelmpi except that it explicitly specifies that vectorization should be for Intel Xeon Phi x200 processors making it easier to cross-compile. For users with recent installations of Intel Parallel Studio, the process can be as simple as: make yes-user-intel source /opt/intel/parallel_studio_xe_2016.3.067/psxevars.sh # or psxevars.csh for C-shell make intel_cpu_intelmpi :pre Alternatively, the build can be accomplished with the src/Make.py script, described in "Section 2.4"_Section_start.html#start_4 of the manual. Type "Make.py -h" for help. For an example: Make.py -v -p intel omp -intel cpu -a file intel_cpu_intelmpi :pre Note that if you build with support for a Phi coprocessor, the same binary can be used on nodes with or without coprocessors installed. However, if you do not have coprocessors on your system, building without offload support will produce a smaller binary. The general requirements for Makefiles with the USER-INTEL package are as follows. "-DLAMMPS_MEMALIGN=64" is required for CCFLAGS. When using Intel compilers, "-restrict" is required and "-qopenmp" is highly recommended for CCFLAGS and LINKFLAGS. LIB should include "-ltbbmalloc". For builds supporting offload, "-DLMP_INTEL_OFFLOAD" is required for CCFLAGS and "-qoffload" is required for LINKFLAGS. Other recommended CCFLAG options for best performance are "-O2 -fno-alias -ansi-alias -qoverride-limits fp-model fast=2 -no-prec-div". The Make.py command will add all of these automatically. NOTE: The vectorization and math capabilities can differ depending on the CPU. For Intel compilers, the "-x" flag specifies the type of processor for which to optimize. "-xHost" specifies that the compiler should build for the processor used for compiling. For Intel Xeon Phi x200 series processors, this option is "-xMIC-AVX512". For fourth generation Intel Xeon (v4/Broadwell) processors, "-xCORE-AVX2" should be used. For older Intel Xeon processors, "-xAVX" will perform best in general for the different simulations in LAMMPS. The default in most of the example Makefiles is to use "-xHost", however this should not be used when cross-compiling. [Running LAMMPS with the USER-INTEL package:] Running LAMMPS with the USER-INTEL package is similar to normal use with the exceptions that one should 1) specify that LAMMPS should use the USER-INTEL package, 2) specify the number of OpenMP threads, and 3) optionally specify the specific LAMMPS styles that should use the USER-INTEL package. 1) and 2) can be performed from the command-line or by editing the input script. 3) requires editing the input script. Advanced performance tuning options are also described below to get the best performance. When running on a single node (including runs using offload to a coprocessor), best performance is normally obtained by using 1 MPI task per physical core and additional OpenMP threads with SMT. For Intel Xeon processors, 2 OpenMP threads should be used for SMT. For Intel Xeon Phi CPUs, 2 or 4 OpenMP threads should be used (best choice depends on the simulation). In cases where the user specifies that LRT mode is used (described below), 1 or 3 OpenMP threads should be used. For multi-node runs, using 1 MPI task per physical core will often perform best, however, depending on the machine and scale, users might get better performance by decreasing the number of MPI tasks and using more OpenMP threads. For performance, the product of the number of MPI tasks and OpenMP threads should not exceed the number of available hardware threads in almost all cases. NOTE: Setting core affinity is often used to pin MPI tasks and OpenMP threads to a core or group of cores so that memory access can be uniform. Unless disabled at build time, affinity for MPI tasks and OpenMP threads on the host (CPU) will be set by default on the host {when using offload to a coprocessor}. In this case, it is unnecessary to use other methods to control affinity (e.g. taskset, numactl, I_MPI_PIN_DOMAIN, etc.). This can be disabled with the {no_affinity} option to the "package intel"_package.html command or by disabling the option at build time (by adding -DINTEL_OFFLOAD_NOAFFINITY to the CCFLAGS line of your Makefile). Disabling this option is not recommended, especially when running on a machine with Intel Hyper-Threading technology disabled. [Run with the USER-INTEL package from the command line:] To enable USER-INTEL optimizations for all available styles used in the input script, the "-sf intel" "command-line switch"_Section_start.html#start_7 can be used without any requirement for editing the input script. This switch will automatically append "intel" to styles that support it. It also invokes a default command: "package intel 1"_package.html. This package command is used to set options for the USER-INTEL package. The default package command will specify that USER-INTEL calculations are performed in mixed precision, that the number of OpenMP threads is specified by the OMP_NUM_THREADS environment variable, and that if coprocessors are present and the binary was built with offload support, that 1 coprocessor per node will be used with automatic balancing of work between the CPU and the coprocessor. You can specify different options for the USER-INTEL package by using the "-pk intel Nphi" "command-line switch"_Section_start.html#start_7 with keyword/value pairs as specified in the documentation. Here, Nphi = # of Xeon Phi coprocessors/node (ignored without offload support). Common options to the USER-INTEL package include {omp} to override any OMP_NUM_THREADS setting and specify the number of OpenMP threads, {mode} to set the floating-point precision mode, and {lrt} to enable Long-Range Thread mode as described below. See the "package intel"_package.html command for details, including the default values used for all its options if not specified, and how to set the number of OpenMP threads via the OMP_NUM_THREADS environment variable if desired. Examples (see documentation for your MPI/Machine for differences in launching MPI applications): mpirun -np 72 -ppn 36 lmp_machine -sf intel -in in.script # 2 nodes, 36 MPI tasks/node, $OMP_NUM_THREADS OpenMP Threads mpirun -np 72 -ppn 36 lmp_machine -sf intel -in in.script -pk intel 0 omp 2 mode double # Don't use any coprocessors that might be available, use 2 OpenMP threads for each task, use double precision :pre [Or run with the USER-INTEL package by editing an input script:] As an alternative to adding command-line arguments, the input script can be edited to enable the USER-INTEL package. This requires adding the "package intel"_package.html command to the top of the input script. For the second example above, this would be: package intel 0 omp 2 mode double :pre To enable the USER-INTEL package only for individual styles, you can add an "intel" suffix to the individual style, e.g.: pair_style lj/cut/intel 2.5 :pre Alternatively, the "suffix intel"_suffix.html command can be added to the input script to enable USER-INTEL styles for the commands that follow in the input script. [Tuning for Performance:] NOTE: The USER-INTEL package will perform better with modifications to the input script when "PPPM"_kspace_style.html is used: -"kspace_modify diff ad"_kspace_modify.html should be added to the +"kspace_modify diff ad"_kspace_modify.html should be added to the input script. Long-Range Thread (LRT) mode is an option to the "package intel"_package.html command that can improve performance when using "PPPM"_kspace_style.html for long-range electrostatics on processors with SMT. It generates an extra pthread for each MPI task. The thread is dedicated to performing some of the PPPM calculations and MPI communications. On Intel Xeon Phi x200 series CPUs, this will likely always improve performance, even on a single node. On Intel Xeon processors, using this mode might result in better performance when using multiple nodes, depending on the machine. To use this mode, specify that the number of OpenMP threads is one less than would normally be used for the run and add the "lrt yes" option to the "-pk" command-line suffix or "package intel" command. For example, if a run would normally perform best with "-pk intel 0 omp 4", instead use "-pk intel 0 omp 3 lrt yes". When using LRT, you should set the environment variable "KMP_AFFINITY=none". LRT mode is not supported when using offload. NOTE: Changing the "newton"_newton.html setting to off can improve performance and/or scalability for simple 2-body potentials such as lj/cut or when using LRT mode on processors supporting AVX-512. Not all styles are supported in the USER-INTEL package. You can mix the USER-INTEL package with styles from the "OPT"_accelerate_opt.html package or the "USER-OMP package"_accelerate_omp.html. Of course, this requires that these packages were installed at build time. This can performed automatically by using "-sf hybrid intel opt" or "-sf hybrid intel omp" command-line options. Alternatively, the "opt" and "omp" suffixes can be appended manually in the input script. For the latter, the "package omp"_package.html command must be in the input script or the "-pk omp Nt" "command-line switch"_Section_start.html#start_7 must be used where Nt is the number of OpenMP threads. The number of OpenMP threads should not be set differently for the different packages. Note that the "suffix hybrid intel omp"_suffix.html command can also be used within the input script to automatically append the "omp" suffix to styles when USER-INTEL styles are not available. When running on many nodes, performance might be better when using fewer OpenMP threads and more MPI tasks. This will depend on the simulation and the machine. Using the "verlet/split"_run_style.html run style might also give better performance for simulations with "PPPM"_kspace_style.html electrostatics. Note that this is an alternative to LRT mode and the two cannot be used together. Currently, when using Intel MPI with Intel Xeon Phi x200 series CPUs, better performance might be obtained by setting the environment variable "I_MPI_SHM_LMT=shm" for Linux kernels that do not yet have full support for AVX-512. Runs on Intel Xeon Phi x200 series processors will always perform better using MCDRAM. Please consult your system documentation for the best approach to specify that MPI runs are performed in MCDRAM. [Tuning for Offload Performance:] The default settings for offload should give good performance. When using LAMMPS with offload to Intel coprocessors, best performance will typically be achieved with concurrent calculations performed on both the CPU and the coprocessor. This is achieved by offloading only a fraction of the neighbor and pair computations to the coprocessor or using "hybrid"_pair_hybrid.html pair styles where only one style uses the "intel" suffix. For simulations with long-range electrostatics or bond, angle, dihedral, improper calculations, computation and data transfer to the coprocessor will run concurrently with computations and MPI communications for these calculations on the host CPU. This is illustrated in the figure below for the rhodopsin protein benchmark running on E5-2697v2 processors with a Intel Xeon Phi 7120p coprocessor. In this plot, the vertical access is time and routines running at the same time are running concurrently on both the host and the coprocessor. :c,image(JPG/offload_knc.png) The fraction of the offloaded work is controlled by the {balance} keyword in the "package intel"_package.html command. A balance of 0 runs all calculations on the CPU. A balance of 1 runs all supported calculations on the coprocessor. A balance of 0.5 runs half of the calculations on the coprocessor. Setting the balance to -1 (the default) will enable dynamic load balancing that continously adjusts the fraction of offloaded work throughout the simulation. Because data transfer cannot be timed, this option typically produces results within 5 to 10 percent of the optimal fixed balance. If running short benchmark runs with dynamic load balancing, adding a short warm-up run (10-20 steps) will allow the load-balancer to find a near-optimal setting that will carry over to additional runs. The default for the "package intel"_package.html command is to have all the MPI tasks on a given compute node use a single Xeon Phi coprocessor. In general, running with a large number of MPI tasks on each node will perform best with offload. Each MPI task will automatically get affinity to a subset of the hardware threads available on the coprocessor. For example, if your card has 61 cores, with 60 cores available for offload and 4 hardware threads per core (240 total threads), running with 24 MPI tasks per node will cause each MPI task to use a subset of 10 threads on the coprocessor. Fine tuning of the number of threads to use per MPI task or the number of threads to use per core can be accomplished with keyword settings of the "package intel"_package.html command. The USER-INTEL package has two modes for deciding which atoms will be handled by the coprocessor. This choice is controlled with the {ghost} keyword of the "package intel"_package.html command. When set to 0, ghost atoms (atoms at the borders between MPI tasks) are not offloaded to the card. This allows for overlap of MPI communication of forces with computation on the coprocessor when the "newton"_newton.html setting is "on". The default is dependent on the style being used, however, better performance may be achieved by setting this option explicitly. When using offload with CPU Hyper-Threading disabled, it may help performance to use fewer MPI tasks and OpenMP threads than available cores. This is due to the fact that additional threads are generated internally to handle the asynchronous offload tasks. If pair computations are being offloaded to an Intel Xeon Phi coprocessor, a diagnostic line is printed to the screen (not to the log file), during the setup phase of a run, indicating that offload mode is being used and indicating the number of coprocessor threads per MPI task. Additionally, an offload timing summary is printed at the end of each run. When offloading, the frequency for "atom sorting"_atom_modify.html is changed to 1 so that the per-atom data is effectively sorted at every rebuild of the neighbor lists. All the available coprocessor threads on each Phi will be divided among MPI tasks, unless the {tptask} option of the "-pk intel" "command-line switch"_Section_start.html#start_7 is used to limit the coprocessor threads per MPI task. [Restrictions:] When offloading to a coprocessor, "hybrid"_pair_hybrid.html styles that require skip lists for neighbor builds cannot be offloaded. Using "hybrid/overlay"_pair_hybrid.html is allowed. Only one intel accelerated style may be used with hybrid styles. "Special_bonds"_special_bonds.html exclusion lists are not currently supported with offload, however, the same effect can often be accomplished by setting cutoffs for excluded atom types to 0. None of the pair styles in the USER-INTEL package currently support the "inner", "middle", "outer" options for rRESPA integration via the "run_style respa"_run_style.html command; only the "pair" option is supported. [References:] Brown, W.M., Carrillo, J.-M.Y., Mishra, B., Gavhane, N., Thakker, F.M., De Kraker, A.R., Yamada, M., Ang, J.A., Plimpton, S.J., "Optimizing Classical Molecular Dynamics in LAMMPS," in Intel Xeon Phi Processor High Performance Programming: Knights Landing Edition, J. Jeffers, J. Reinders, A. Sodani, Eds. Morgan Kaufmann. :ulb,l Brown, W. M., Semin, A., Hebenstreit, M., Khvostov, S., Raman, K., Plimpton, S.J. "Increasing Molecular Dynamics Simulation Rates with an 8-Fold Increase in Electrical Power Efficiency."_http://dl.acm.org/citation.cfm?id=3014915 2016 High Performance Computing, Networking, Storage and Analysis, SC16: International Conference (pp. 82-95). :l Brown, W.M., Carrillo, J.-M.Y., Gavhane, N., Thakkar, F.M., Plimpton, S.J. Optimizing Legacy Molecular Dynamics Software with Directive-Based Offload. Computer Physics Communications. 2015. 195: p. 95-101. :l :ule diff --git a/doc/src/bond_oxdna.txt b/doc/src/bond_oxdna.txt index f9b35a167..2add6f4c2 100644 --- a/doc/src/bond_oxdna.txt +++ b/doc/src/bond_oxdna.txt @@ -1,79 +1,79 @@ "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 bond_style oxdna/fene command :h3 bond_style oxdna2/fene command :h3 [Syntax:] bond_style oxdna/fene :pre bond_style oxdna2/fene :pre [Examples:] bond_style oxdna/fene bond_coeff * 2.0 0.25 0.7525 :pre bond_style oxdna2/fene bond_coeff * 2.0 0.25 0.7564 :pre [Description:] The {oxdna/fene} and {oxdna2/fene} bond styles use the potential :c,image(Eqs/bond_oxdna_fene.jpg) to define a modified finite extensible nonlinear elastic (FENE) potential "(Ouldridge)"_#oxdna_fene to model the connectivity of the phosphate backbone -in the oxDNA force field for coarse-grained modelling of DNA. +in the oxDNA force field for coarse-grained modelling of DNA. The following coefficients must be defined for the bond type via the "bond_coeff"_bond_coeff.html command as given in the above example, or in the data file or restart files read by the "read_data"_read_data.html or "read_restart"_read_restart.html commands: epsilon (energy) Delta (distance) r0 (distance) :ul NOTE: The oxDNA bond style has to be used together with the corresponding oxDNA pair styles for excluded volume interaction {oxdna/excv}, stacking {oxdna/stk}, cross-stacking {oxdna/xstk} -and coaxial stacking interaction {oxdna/coaxstk} as well as hydrogen-bonding interaction {oxdna/hbond} (see also documentation of -"pair_style oxdna/excv"_pair_oxdna.html). For the oxDNA2 "(Snodin)"_#oxdna2 bond style the analogous pair styles and an additional Debye-Hueckel pair +and coaxial stacking interaction {oxdna/coaxstk} as well as hydrogen-bonding interaction {oxdna/hbond} (see also documentation of +"pair_style oxdna/excv"_pair_oxdna.html). For the oxDNA2 "(Snodin)"_#oxdna2 bond style the analogous pair styles and an additional Debye-Hueckel pair style {oxdna2/dh} have to be defined. The coefficients in the above example have to be kept fixed and cannot be changed without reparametrizing the entire model. Example input and data files for DNA duplexes can be found in examples/USER/cgdna/examples/oxDNA/ and /oxDNA2/. A simple python setup tool which creates single straight or helical DNA strands, DNA duplexes or arrays of DNA duplexes can be found in examples/USER/cgdna/util/. A technical report with more information on the model, the structure of the input file, the setup tool and the performance of the LAMMPS-implementation of oxDNA can be found "here"_PDF/USER-CGDNA-overview.pdf. :line [Restrictions:] This bond style can only be used if LAMMPS was built with the USER-CGDNA package and the MOLECULE and ASPHERE package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info on packages. [Related commands:] -"pair_style oxdna/excv"_pair_oxdna.html, "pair_style oxdna2/excv"_pair_oxdna2.html, "fix nve/dotc/langevin"_fix_nve_dotc_langevin.html, "bond_coeff"_bond_coeff.html +"pair_style oxdna/excv"_pair_oxdna.html, "pair_style oxdna2/excv"_pair_oxdna2.html, "fix nve/dotc/langevin"_fix_nve_dotc_langevin.html, "bond_coeff"_bond_coeff.html [Default:] none :line :link(oxdna_fene) [(Ouldridge)] T.E. Ouldridge, A.A. Louis, J.P.K. Doye, J. Chem. Phys. 134, 085101 (2011). :link(oxdna2) [(Snodin)] B.E. Snodin, F. Randisi, M. Mosayebi, et al., J. Chem. Phys. 142, 234901 (2015). diff --git a/doc/src/compute_cnp_atom.txt b/doc/src/compute_cnp_atom.txt index 9aa63c84d..16a51f524 100644 --- a/doc/src/compute_cnp_atom.txt +++ b/doc/src/compute_cnp_atom.txt @@ -1,111 +1,111 @@ "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 cnp/atom command :h3 [Syntax:] compute ID group-ID cnp/atom cutoff :pre ID, group-ID are documented in "compute"_compute.html command cnp/atom = style name of this compute command cutoff = cutoff distance for nearest neighbors (distance units) :ul [Examples:] compute 1 all cnp/atom 3.08 :pre [Description:] Define a computation that calculates the Common Neighborhood Parameter (CNP) for each atom in the group. In solid-state systems the CNP is a useful measure of the local crystal structure around an atom and can be used to characterize whether the atom is part of a perfect lattice, a local defect (e.g. a dislocation or stacking fault), or at a surface. The value of the CNP parameter will be 0.0 for atoms not in the specified compute group. Note that normally a CNP calculation should only be performed on single component systems. This parameter is computed using the following formula from "(Tsuzuki)"_#Tsuzuki2 :c,image(Eqs/cnp_eq.jpg) where the index {j} goes over the {n}i nearest neighbors of atom {i}, and the index {k} goes over the {n}ij common nearest neighbors between atom {i} and atom {j}. Rik and Rjk are the vectors connecting atom {k} to atoms {i} and {j}. The quantity in the double sum is computed -for each atom. +for each atom. The CNP calculation is sensitive to the specified cutoff value. You should ensure that the appropriate nearest neighbors of an atom are found within the cutoff distance for the presumed crystal structure. E.g. 12 nearest neighbor for perfect FCC and HCP crystals, 14 nearest neighbors for perfect BCC crystals. These formulas can be used to obtain a good cutoff distance: :c,image(Eqs/cnp_cutoff.jpg) where a is the lattice constant for the crystal structure concerned and in the HCP case, x = (c/a) / 1.633, where 1.633 is the ideal c/a for HCP crystals. Also note that since the CNP calculation in LAMMPS uses the neighbors of an owned atom to find the nearest neighbors of a ghost atom, the following relation should also be satisfied: :c,image(Eqs/cnp_cutoff2.jpg) where Rc is the cutoff distance of the potential, Rs is the skin distance as specified by the "neighbor"_neighbor.html command, and cutoff is the argument used with the compute cnp/atom command. LAMMPS will issue a warning if this is not the case. The neighbor list needed to compute this quantity is constructed each time the calculation is performed (e.g. each time a snapshot of atoms is dumped). Thus it can be inefficient to compute/dump this quantity too frequently or to have multiple compute/dump commands, each with a {cnp/atom} style. [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 real positive numbers. Some typical CNP values: FCC lattice = 0.0 BCC lattice = 0.0 HCP lattice = 4.4 :pre FCC (111) surface ~ 13.0 FCC (100) surface ~ 26.5 FCC dislocation core ~ 11 :pre [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:] "compute cna/atom"_compute_cna_atom.html "compute centro/atom"_compute_centro_atom.html [Default:] none :line :link(Tsuzuki2) [(Tsuzuki)] Tsuzuki, Branicio, Rino, Comput Phys Comm, 177, 518 (2007). diff --git a/doc/src/compute_pair_local.txt b/doc/src/compute_pair_local.txt index 012121099..16aaba466 100644 --- a/doc/src/compute_pair_local.txt +++ b/doc/src/compute_pair_local.txt @@ -1,138 +1,140 @@ "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 pair/local command :h3 [Syntax:] compute ID group-ID pair/local value1 value2 ... keyword args ... :pre ID, group-ID are documented in "compute"_compute.html command :ulb,l pair/local = style name of this compute command :l one or more values may be appended :l value = {dist} or {eng} or {force} or {fx} or {fy} or {fz} or {pN} :l {dist} = pairwise distance {eng} = pairwise energy {force} = pairwise force {fx},{fy},{fz} = components of pairwise force {pN} = pair style specific quantities for allowed N values :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 pair/local eng compute 1 all pair/local dist eng force compute 1 all pair/local dist eng fx fy fz compute 1 all pair/local dist fx fy fz p1 p2 p3 :pre [Description:] Define a computation that calculates properties of individual pairwise interactions. The number of datums generated, aggregated across all processors, equals the number of pairwise interactions in the system. The local data stored by this command 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, and if the current pairwise distance is less than the force cutoff distance for that interaction, as defined by the "pair_style"_pair_style.html and "pair_coeff"_pair_coeff.html commands. The value {dist} is the distance between the pair of atoms. The value {eng} is the interaction energy for the pair of atoms. The value {force} is the force acting between the pair of atoms, which is positive for a repulsive force and negative for an attractive force. The values {fx}, {fy}, and {fz} are the xyz components of {force} on atom I. A pair style may define additional pairwise quantities which can be accessed as {p1} to {pN}, where N is defined by the pair style. Most pair styles do not define any additional quantities, so N = 0. An example of ones that do are the "granular pair styles"_pair_gran.html which calculate the tangential force between two particles and return its components and magnitude acting on atom I for N = 1,2,3,4. See individual pair styles for detils. The value {dist} will be in distance "units"_units.html. The value {eng} will be in energy "units"_units.html. The values {force}, {fx}, {fy}, and {fz} will be in force "units"_units.html. The values {pN} will be in whatever units the pair style defines. The optional {cutoff} keyword determines how the force cutoff distance for an interaction is determined. 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. +styles"_pair_gran.txt. Note that if a granular model defines atom +types such that all particles of a specific type are monodisperse +(same diameter), then the two settings are effectively identical. 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, pair output from the "compute property/local"_compute_property_local.html command can be combined with data from this command and output by the "dump local"_dump.html command in a consistent way. Here is an example of how to do this: compute 1 all property/local patom1 patom2 compute 2 all pair/local dist eng force dump 1 all local 1000 tmp.dump index c_1\[1\] c_1\[2\] c_2\[1\] c_2\[2\] c_2\[3\] :pre 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 will 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. An exception is if long-range Coulombics are being computed via the "kspace_style"_kspace_style.html command, then atom pairs with weighting factors of zero are still included in the neighbor list, so that a portion of the long-range interaction contribution can be computed in the pair style. Hence in that case, those atom pairs will be part of the local data created by this command. [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 pairs. 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 output for {dist} will be in distance "units"_units.html. The output for {eng} will be in energy "units"_units.html. The output for {force}, {fx}, {fy}, and {fz} will be in force "units"_units.html. The outpur for {pN} will be in whatever units the pair style defines. [Restrictions:] none [Related commands:] "dump local"_dump.html, "compute property/local"_compute_property_local.html [Default:] The keyword default is cutoff = type. diff --git a/doc/src/compute_property_local.txt b/doc/src/compute_property_local.txt index f7851e864..39106a39c 100644 --- a/doc/src/compute_property_local.txt +++ b/doc/src/compute_property_local.txt @@ -1,155 +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 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 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.html. +Note that if a granular model defines atom types such that all +particles of a specific type are monodisperse (same diameter), then +the two settings are effectively identical. 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. [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/dihedral_charmm.txt b/doc/src/dihedral_charmm.txt index 918755ec3..73dc67cde 100644 --- a/doc/src/dihedral_charmm.txt +++ b/doc/src/dihedral_charmm.txt @@ -1,159 +1,167 @@ "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 dihedral_style charmm command :h3 dihedral_style charmm/intel command :h3 dihedral_style charmm/kk command :h3 dihedral_style charmm/omp command :h3 dihedral_style charmmfsw command :h3 [Syntax:] dihedral_style style :pre style = {charmm} or {charmmfsw} :ul [Examples:] dihedral_style charmm dihedral_style charmmfsw dihedral_coeff 1 0.2 1 180 1.0 dihedral_coeff 2 1.8 1 0 1.0 dihedral_coeff 1 3.1 2 180 0.5 :pre [Description:] The {charmm} and {charmmfsw} dihedral styles use the potential :c,image(Eqs/dihedral_charmm.jpg) See "(MacKerell)"_#dihedral-MacKerell for a description of the CHARMM force field. This dihedral style can also be used for the AMBER force field (see comment on weighting factors below). See "(Cornell)"_#dihedral-Cornell for a description of the AMBER force field. NOTE: The newer {charmmfsw} style was released in March 2017. We recommend it be used instead of the older {charmm} style when running a simulation with the CHARMM force field, either with long-range Coulombics or a Coulomb cutoff, via the "pair_style lj/charmmfsw/coul/long"_pair_charmm.html and "pair_style lj/charmmfsw/coul/charmmfsh"_pair_charmm.html commands respectively. Otherwise the older {charmm} style is fine to use. See the discussion below and more details on the "pair_style charmm"_pair_charmm.html doc page. The following coefficients must be defined for each dihedral type via the "dihedral_coeff"_dihedral_coeff.html command as in the example above, or in the data file or restart files read by the "read_data"_read_data.html or "read_restart"_read_restart.html commands: K (energy) n (integer >= 0) d (integer value of degrees) weighting factor (1.0, 0.5, or 0.0) :ul The weighting factor is required to correct for double counting pairwise non-bonded Lennard-Jones interactions in cyclic systems or when using the CHARMM dihedral style with non-CHARMM force fields. With the CHARMM dihedral style, interactions between the 1st and 4th atoms in a dihedral are skipped during the normal non-bonded force computation and instead evaluated as part of the dihedral using special epsilon and sigma values specified with the "pair_coeff"_pair_charmm.html command of pair styles that contain "lj/charmm" (e.g. "pair_style lj/charmm/coul/long"_pair_charmm.html) In 6-membered rings, the same 1-4 interaction would be computed twice (once for the clockwise 1-4 pair in dihedral 1-2-3-4 and once in the counterclockwise dihedral 1-6-5-4) and thus the weighting factor has to be 0.5 in this case. In 4-membered or 5-membered rings, the 1-4 dihedral also is counted as a 1-2 or 1-3 interaction when going around the ring in the opposite direction and thus the weighting factor is 0.0, as the 1-2 and 1-3 exclusions take precedence. Note that this dihedral weighting factor is unrelated to the scaling factor specified by the "special bonds"_special_bonds.html command which applies to all 1-4 interactions in the system. For CHARMM force fields, the special_bonds 1-4 interaction scaling factor should be set to 0.0. Since the corresponding 1-4 non-bonded interactions are computed with the dihedral. This means that if any of the weighting factors defined as dihedral coefficients (4th coeff above) are non-zero, then you must use a pair style with "lj/charmm" and set the special_bonds 1-4 scaling factor to 0.0 (which is the default). Otherwise 1-4 non-bonded interactions in dihedrals will be computed twice. For simulations using the CHARMM force field with a Coulomb cutoff, the difference between the {charmm} and {charmmfsw} styles is in the computation of the 1-4 non-bond interactions, though only if the distance between the two atoms is within the switching region of the pairwise potential defined by the corresponding CHARMM pair style, i.e. within the outer cutoff specified for the pair style. The {charmmfsw} style should only be used when using the corresponding "pair_style lj/charmmfsw/coul/charmmfsw"_pair_charmm.html or "pair_style lj/charmmfsw/coul/long"_pair_charmm.html commands. Use the {charmm} style with the older "pair_style"_pair_charmm.html commands that have just "charmm" in their style name. See the discussion on the "CHARMM pair_style"_pair_charmm.html doc page for details. Note that for AMBER force fields, which use pair styles with "lj/cut", the special_bonds 1-4 scaling factor should be set to the AMBER defaults (1/2 and 5/6) and all the dihedral weighting factors (4th coeff above) must be set to 0.0. In this case, you can use any pair style you wish, since the dihedral does not need any Lennard-Jones parameter information and will not compute any 1-4 non-bonded interactions. Likewise the {charmm} or {charmmfsw} styles are identical in this case since no 1-4 non-bonded interactions are computed. :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 dihedral style can only be used if LAMMPS was built with the +When using run_style "respa"_run_style.html, these dihedral styles +must be assigned to the same r-RESPA level as {pair} or {outer}. + +When used in combination with CHARMM pair styles, the 1-4 +"special_bonds"_special_bonds.html scaling factors must be set to 0.0. +Otherwise non-bonded contributions for these 1-4 pairs will be +computed multiple times. + +These dihedral styles can only be used if LAMMPS was built with the MOLECULE package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info on packages. [Related commands:] "dihedral_coeff"_dihedral_coeff.html [Default:] none :line :link(dihedral-Cornell) [(Cornell)] Cornell, Cieplak, Bayly, Gould, Merz, Ferguson, Spellmeyer, Fox, Caldwell, Kollman, JACS 117, 5179-5197 (1995). :link(dihedral-MacKerell) [(MacKerell)] MacKerell, Bashford, Bellott, Dunbrack, Evanseck, Field, Fischer, Gao, Guo, Ha, et al, J Phys Chem B, 102, 3586 (1998). diff --git a/doc/src/dump_vtk.txt b/doc/src/dump_vtk.txt index 21502e7f4..d4d28c81f 100644 --- a/doc/src/dump_vtk.txt +++ b/doc/src/dump_vtk.txt @@ -1,179 +1,179 @@ "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 vtk command :h3 [Syntax:] dump ID group-ID vtk N file args :pre ID = user-assigned name for the dump group-ID = ID of the group of atoms to be dumped vtk = style of dump command (other styles {atom} or {cfg} or {dcd} or {xtc} or {xyz} or {local} or {custom} are discussed on the "dump"_dump.html doc page) N = dump every this many timesteps -file = name of file to write dump info to +file = name of file to write dump info to args = same as arguments for "dump_style custom"_dump.html :ul [Examples:] dump dmpvtk all vtk 100 dump*.myforce.vtk id type vx fx dump dmpvtp flow vtk 100 dump*.%.displace.vtp id type c_myD\[1\] c_myD\[2\] c_myD\[3\] v_ke :pre [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. This dump style is similar to "dump_style custom"_dump.html but uses the VTK library to write data to VTK simple legacy or XML format depending on the filename extension specified for the dump file. This can be either {*.vtk} for the legacy format or {*.vtp} and {*.vtu}, respectively, for 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), the "dump_modify binary"_dump_modify.html command allows setting of a binary option for this dump style explicitly. 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 {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 {vtk} allows you to specify a list of atom attributes to be -written to the dump file for each atom. The list of possible attributes +written to the dump file for each atom. The list of possible attributes is the same as for the "dump_style custom"_dump.html command; see its doc page for a listing and an explanation of each attribute. NOTE: Since position data is required to write VTK files the atom attributes "x y z" do not have to be specified explicitly; they will be included in the dump file regardless. Also, in contrast to the {custom} style, the specified {vtk} 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. 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 [Restrictions:] The {vtk} style does not support writing of gzipped dump files. The {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 {vtk} dump style supports neither buffering or 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/fix_box_relax.txt b/doc/src/fix_box_relax.txt index 54decd628..e3d75ee85 100644 --- a/doc/src/fix_box_relax.txt +++ b/doc/src/fix_box_relax.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 box/relax command :h3 [Syntax:] fix ID group-ID box/relax keyword value ... :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l box/relax = style name of this fix command :l one or more keyword value pairs may be appended keyword = {iso} or {aniso} or {tri} or {x} or {y} or {z} or {xy} or {yz} or {xz} or {couple} or {nreset} or {vmax} or {dilate} or {scaleyz} or {scalexz} or {scalexy} or {fixedpoint} {iso} or {aniso} or {tri} value = Ptarget = desired pressure (pressure units) {x} or {y} or {z} or {xy} or {yz} or {xz} value = Ptarget = desired pressure (pressure units) {couple} = {none} or {xyz} or {xy} or {yz} or {xz} {nreset} value = reset reference cell every this many minimizer iterations {vmax} value = fraction = max allowed volume change in one iteration {dilate} value = {all} or {partial} {scaleyz} value = {yes} or {no} = scale yz with lz {scalexz} value = {yes} or {no} = scale xz with lz {scalexy} value = {yes} or {no} = scale xy with ly {fixedpoint} values = x y z x,y,z = perform relaxation dilation/contraction around this point (distance units) :pre :ule [Examples:] fix 1 all box/relax iso 0.0 vmax 0.001 fix 2 water box/relax aniso 0.0 dilate partial fix 2 ice box/relax tri 0.0 couple xy nreset 100 :pre [Description:] Apply an external pressure or stress tensor to the simulation box during an "energy minimization"_minimize.html. This allows the box size and shape to vary during the iterations of the minimizer so that the final configuration will be both an energy minimum for the potential energy of the atoms, and the system pressure tensor will be close to the specified external tensor. Conceptually, specifying a positive pressure is like squeezing on the simulation box; a negative pressure typically allows the box to expand. :line The external pressure tensor is specified using one or more of the {iso}, {aniso}, {tri}, {x}, {y}, {z}, {xy}, {xz}, {yz}, and {couple} keywords. These keywords give you the ability to specify all 6 components of an external stress tensor, and to couple various of these components together so that the dimensions they represent are varied together during the minimization. Orthogonal simulation boxes have 3 adjustable dimensions (x,y,z). Triclinic (non-orthogonal) simulation boxes have 6 adjustable dimensions (x,y,z,xy,xz,yz). 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. The target pressures {Ptarget} for each of the 6 components of the stress tensor can be specified independently via the {x}, {y}, {z}, {xy}, {xz}, {yz} keywords, which correspond to the 6 simulation box dimensions. For example, if the {y} keyword is used, the y-box length will change during the minimization. If the {xy} keyword is used, the xy tilt factor will change. A box dimension will not change if that component is not specified. Note that in order to use the {xy}, {xz}, or {yz} keywords, the simulation box must be triclinic, even if its initial tilt factors are 0.0. When the size of the simulation box changes, all atoms are re-scaled to new positions, unless the keyword {dilate} is specified with a value of {partial}, in which case only the atoms in the fix group are re-scaled. This can be useful for leaving the coordinates of atoms in a solid substrate unchanged and controlling the pressure of a surrounding fluid. The {scaleyz}, {scalexz}, and {scalexy} keywords control whether or not the corresponding tilt factors are scaled with the associated box dimensions when relaxing triclinic periodic cells. The default values {yes} will turn on scaling, which corresponds to adjusting the linear dimensions of the cell while preserving its shape. Choosing {no} ensures that the tilt factors are not scaled with the box dimensions. See below for restrictions and default values in different situations. In older versions of LAMMPS, scaling of tilt factors was not performed. The old behavior can be recovered by setting all three scale keywords to {no}. The {fixedpoint} keyword specifies the fixed point for cell relaxation. By default, it is the center of the box. Whatever point is chosen will not move during the simulation. For example, if the lower periodic boundaries pass through (0,0,0), and this point is provided to {fixedpoint}, then the lower periodic boundaries will remain at (0,0,0), while the upper periodic boundaries will move twice as far. In all cases, the particle positions at each iteration are unaffected by the chosen value, except that all particles are displaced by the same amount, different on each iteration. NOTE: Applying an external pressure to tilt dimensions {xy}, {xz}, {yz} can sometimes result in arbitrarily large values of the tilt factors, i.e. a dramatically deformed simulation box. This typically indicates that there is something badly wrong with how the simulation was constructed. The two most common sources of this error are applying a shear stress to a liquid system or specifying an external shear stress tensor that exceeds the yield stress of the solid. In either case the minimization may converge to a bogus conformation or not converge at all. Also note that if the box shape tilts to an extreme shape, 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. NOTE: Performing a minimization with this fix is not a mathematically well-defined minimization problem. This is because the objective function being minimized changes if the box size/shape changes. In practice this means the minimizer can get "stuck" before you have reached the desired tolerance. The solution to this is to restart the minimizer from the new adjusted box size/shape, since that creates a new objective function valid for the new box size/shape. Repeat as necessary until the box size/shape has reached its new equilibrium. :line :line :line The {couple} keyword allows two or three of the diagonal components of the pressure tensor to be "coupled" together. The value specified with the keyword determines which are coupled. For example, {xz} means the {Pxx} and {Pzz} components of the stress tensor are coupled. {Xyz} means all 3 diagonal components are coupled. Coupling means two things: the instantaneous stress will be computed as an average of the corresponding diagonal components, and the coupled box dimensions will be changed together in lockstep, meaning coupled dimensions will be dilated or contracted by the same percentage every timestep. The {Ptarget} values for any coupled dimensions must be identical. {Couple xyz} can be used for a 2d simulation; the {z} dimension is simply ignored. :line The {iso}, {aniso}, and {tri} keywords are simply shortcuts that are equivalent to specifying several other keywords together. The keyword {iso} means couple all 3 diagonal components together when pressure is computed (hydrostatic pressure), and dilate/contract the dimensions together. Using "iso Ptarget" is the same as specifying these 4 keywords: x Ptarget y Ptarget z Ptarget couple xyz :pre The keyword {aniso} means {x}, {y}, and {z} dimensions are controlled independently using the {Pxx}, {Pyy}, and {Pzz} components of the stress tensor as the driving forces, and the specified scalar external pressure. Using "aniso Ptarget" is the same as specifying these 4 keywords: x Ptarget y Ptarget z Ptarget couple none :pre The keyword {tri} means {x}, {y}, {z}, {xy}, {xz}, and {yz} dimensions are controlled independently using their individual stress components as the driving forces, and the specified scalar pressure as the external normal stress. Using "tri Ptarget" is the same as specifying these 7 keywords: x Ptarget y Ptarget z Ptarget xy 0.0 yz 0.0 xz 0.0 couple none :pre :line The {vmax} keyword can be used to limit the fractional change in the volume of the simulation box that can occur in one iteration of the minimizer. If the pressure is not settling down during the minimization this can be because the volume is fluctuating too much. The specified fraction must be greater than 0.0 and should be << 1.0. A value of 0.001 means the volume cannot change by more than 1/10 of a percent in one iteration when {couple xyz} has been specified. For any other case it means no linear dimension of the simulation box can change by more than 1/10 of a percent. :line With this fix, the potential energy used by the minimizer is augmented by an additional energy provided by the fix. The overall objective function then is: :c,image(Eqs/fix_box_relax1.jpg) where {U} is the system potential energy, {P}_t is the desired hydrostatic pressure, {V} and {V}_0 are the system and reference volumes, respectively. {E}_{strain} is the strain energy expression proposed by Parrinello and Rahman "(Parrinello1981)"_#Parrinello1981. Taking derivatives of {E} w.r.t. the box dimensions, and setting these to zero, we find that at the minimum of the objective function, the global system stress tensor [P] will satisfy the relation: :c,image(Eqs/fix_box_relax2.jpg) where [I] is the identity matrix, [h]_0 is the box dimension tensor of the reference cell, and [h]_0{d} is the diagonal part of [h]_0. [S]_{t} is a symmetric stress tensor that is chosen by LAMMPS so that the upper-triangular components of [P] equal the stress tensor specified by the user. This equation only applies when the box dimensions are equal to those of the reference dimensions. If this is not the case, then the converged stress tensor will not equal that specified by the user. We can resolve this problem by periodically resetting the reference dimensions. The keyword {nreset_ref} controls how often this is done. If this keyword is not used, or is given a value of zero, then the reference dimensions are set to those of the initial simulation domain and are never changed. A value of {nstep} means that every {nstep} minimization steps, the reference dimensions are set to those of the current simulation domain. Note that resetting the reference dimensions changes the objective function and gradients, which sometimes causes the minimization to fail. This can be resolved by changing the value of {nreset}, or simply continuing the minimization from a restart file. NOTE: As normally computed, pressure includes a kinetic- energy or temperature-dependent component; see the "compute pressure"_compute_pressure.html command. However, atom velocities are ignored during a minimization, and the applied pressure(s) specified with this command are assumed to only be the virial component of the pressure (the non-kinetic portion). Thus if atoms have a non-zero temperature and you print the usual thermodynamic pressure, it may not appear the system is converging to your specified pressure. The solution for this is to either (a) zero the velocities of all atoms before performing the minimization, or (b) make sure you are monitoring the pressure without its kinetic component. The latter can -be done by outputting the pressure from the pressure compute this +be done by outputting the pressure from the pressure compute this command creates (see below) or a pressure compute you define yourself. NOTE: Because pressure is often a very sensitive function of volume, it can be difficult for the minimizer to equilibrate the system the desired pressure with high precision, particularly for solids. Some techniques that seem to help are (a) use the "min_modify line quadratic" option when minimizing with box relaxations, (b) minimize several times in succession if need be, to drive the pressure closer to the target pressure, (c) relax the atom positions before relaxing the box, and (d) relax the box to the target hydrostatic pressure before relaxing to a target shear stress state. Also note that some systems (e.g. liquids) will not sustain a non-hydrostatic applied pressure, which means the minimizer will not converge. :line This fix computes a temperature and pressure each timestep. The temperature is used to compute the kinetic contribution to the pressure, even though this is subsequently ignored by default. 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 virial :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", and the group for the new computes is the same as the fix group. Also note that the pressure compute does not include a kinetic component. Note that these are NOT the computes used by thermodynamic output (see the "thermo_style"_thermo_style.html command) with ID = {thermo_temp} and {thermo_press}. This means you can change the attributes of this fix's temperature or pressure via the "compute_modify"_compute_modify.html command or print this temperature or pressure during thermodynamic output via the "thermo_style custom"_thermo_style.html command using the appropriate compute-ID. It also means that changing attributes of {thermo_temp} or {thermo_press} will have no effect on this fix. :line [Restart, fix_modify, output, run start/stop, minimize info:] No information about this fix is written to "binary restart files"_restart.html. The "fix_modify"_fix_modify.html {temp} and {press} options are supported by this fix. You can use them to assign a "compute"_compute.html you have defined to this fix which will be used in its temperature and pressure calculation, as described above. Note that as described above, if you assign a pressure compute to this fix that includes a kinetic energy component it will affect the minimization, most likely in an undesirable way. NOTE: If both the {temp} and {press} keywords are used in a single thermo_modify command (or in two separate commands), then the order in which the keywords are specified is important. Note that a "pressure compute"_compute_pressure.html defines its own temperature compute as an argument when it is specified. The {temp} keyword will override this (for the pressure compute being used by fix box/relax), but only if the {temp} keyword comes after the {press} keyword. If the {temp} keyword comes before the {press} keyword, then the new pressure compute specified by the {press} keyword will be unaffected by the {temp} setting. This fix computes a global scalar which can be accessed by various "output commands"_Section_howto.html#howto_15. The scalar is the pressure-volume energy, plus the strain energy, if it exists, as described above. The energy values reported at the end of a minimization run under "Minimization stats" include this energy, and so differ from what LAMMPS normally reports as potential energy. This fix does not support the "fix_modify"_fix_modify.html {energy} option, because that would result in double-counting of the fix energy in the minimization energy. Instead, the fix energy can be explicitly added to the potential energy using one of these two variants: variable emin equal pe+f_1 :pre variable emin equal pe+f_1/atoms :pre No parameter of this fix can be used with the {start/stop} keywords of the "run"_run.html command. This fix is invoked during "energy minimization"_minimize.html, but not for the purpose of adding a contribution to the energy or forces being minimized. Instead it alters the simulation box geometry as described above. [Restrictions:] Only dimensions that are available can be adjusted by this fix. Non-periodic dimensions are not available. {z}, {xz}, and {yz}, are not available for 2D simulations. {xy}, {xz}, and {yz} are only available if the simulation domain is non-orthogonal. 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. The {scaleyz yes} and {scalexz yes} keyword/value pairs can not be used for 2D simulations. {scaleyz yes}, {scalexz yes}, and {scalexy yes} options can only be used if the 2nd dimension in the keyword is periodic, and if the tilt factor is not coupled to the barostat via keywords {tri}, {yz}, {xz}, and {xy}. [Related commands:] "fix npt"_fix_nh.html, "minimize"_minimize.html [Default:] The keyword defaults are dilate = all, vmax = 0.0001, nreset = 0. :line :link(Parrinello1981) [(Parrinello1981)] Parrinello and Rahman, J Appl Phys, 52, 7182 (1981). diff --git a/doc/src/fix_eos_table_rx.txt b/doc/src/fix_eos_table_rx.txt index e8d515e1f..e5e4f772f 100644 --- a/doc/src/fix_eos_table_rx.txt +++ b/doc/src/fix_eos_table_rx.txt @@ -1,176 +1,176 @@ "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 eos/table/rx command :h3 [Syntax:] fix ID group-ID eos/table/rx style file1 N keyword ... :pre ID, group-ID are documented in "fix"_fix.html command eos/table/rx = style name of this fix command style = {linear} = method of interpolation file1 = filename containing the tabulated equation of state N = use N values in {linear} tables keyword = name of table keyword corresponding to table file file2 = filename containing the heats of formation of each species (optional) deltaHf = heat of formation for a single species in energy units (optional) energyCorr = energy correction in energy units (optional) tempCorrCoeff = temperature correction coefficient (optional) :ul [Examples:] fix 1 all eos/table/rx linear eos.table 10000 KEYWORD thermo.table fix 1 all eos/table/rx linear eos.table 10000 KEYWORD 1.5 fix 1 all eos/table/rx linear eos.table 10000 KEYWORD 1.5 0.025 0.0 :pre [Description:] Fix {eos/table/rx} applies a tabulated mesoparticle equation of state to relate the concentration-dependent particle internal energy (u_i) to the particle internal temperature (dpdTheta_i). The concentration-dependent particle internal energy (u_i) is computed according to the following relation: :c,image(Eqs/fix_eos_table_rx.jpg) where {m} is the number of species, {c_i,j} is the concentration of species {j} in particle {i}, {u_j} is the internal energy of species j, {DeltaH_f,j} is the heat of formation of species {j}, N is the number of molecules represented by the coarse-grained particle, kb is the Boltzmann constant, and T is the temperature of the system. Additionally, -it is possible to modify the concentration-dependent particle internal -energy relation by adding an energy correction, temperature-dependent +it is possible to modify the concentration-dependent particle internal +energy relation by adding an energy correction, temperature-dependent correction, and/or a molecule-dependent correction. An energy correction can -be specified as a constant (in energy units). A temperature correction can be -specified by multiplying a temperature correction coefficient by the -internal temperature. A molecular correction can be specified by -by multiplying a molecule correction coefficient by the average number of -product gas particles in the coarse-grain particle. +be specified as a constant (in energy units). A temperature correction can be +specified by multiplying a temperature correction coefficient by the +internal temperature. A molecular correction can be specified by +by multiplying a molecule correction coefficient by the average number of +product gas particles in the coarse-grain particle. Fix {eos/table/rx} creates interpolation tables of length {N} from {m} internal energy values of each species {u_j} listed in a file as a function of internal temperature. During a simulation, these tables are used to interpolate internal energy or temperature values as needed. The interpolation is done with the {linear} style. For the {linear} style, the internal temperature is used to find 2 surrounding table values from which an internal energy is computed by linear interpolation. A secant solver is used to determine the internal temperature from the internal energy. The first filename specifies a file containing tabulated internal temperature and {m} internal energy values for each species {u_j}. The keyword specifies a section of the file. The format of this file is described below. The second filename specifies a file containing heat of formation {DeltaH_f,j} for each species. In cases where the coarse-grain particle represents a single molecular -species (i.e., no reactions occur and fix {rx} is not present in the input file), -fix {eos/table/rx} can be applied in a similar manner to fix {eos/table} -within a non-reactive DPD simulation. In this case, the heat of formation +species (i.e., no reactions occur and fix {rx} is not present in the input file), +fix {eos/table/rx} can be applied in a similar manner to fix {eos/table} +within a non-reactive DPD simulation. In this case, the heat of formation filename is replaced with the heat of formation value for the single species. -Additionally, the energy correction and temperature correction coefficients may -also be specified as fix arguments. +Additionally, the energy correction and temperature correction coefficients may +also be specified as fix arguments. :line The format of a tabulated file is as follows (without the parenthesized comments): # EOS TABLE (one or more comment or blank lines) :pre KEYWORD (keyword is first text on line) N 500 h2 no2 n2 ... no (N parameter species1 species2 ... speciesN) (blank) 1 1.00 0.000 ... 0.0000 (index, internal temperature, internal energy of species 1, ..., internal energy of species m) 2 1.02 0.001 ... 0.0002 ... 500 10.0 0.500 ... 1.0000 :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. The first line begins with a keyword which identifies the section. The line can contain additional text, but the initial text must match the argument specified in the fix command. The next line lists the number of table entries and the species names that correspond with all the species listed in the reaction equations through the {fix rx} command. The parameter "N" is required and its value is the number of table entries that follow. Let Nfile = "N" in the tabulated file. What LAMMPS does is a preliminary interpolation by creating splines using the Nfile tabulated values as nodal points. Following a blank line, the next N lines list the tabulated values. On each line, the 1st value is the index from 1 to N, the 2nd value is the internal temperature (in temperature units), the 3rd value until the {m+3} value are the internal energies of the m species (in energy units). Note that all internal temperature and internal energy values must increase from one line to the next. Note that one file can contain many sections, each with a tabulated potential. LAMMPS reads the file section by section until it finds one that matches the specified keyword. :line The format of a heat of formation file is as follows (without the parenthesized comments): # HEAT OF FORMATION TABLE (one or more comment or blank lines) :pre (blank) h2 0.00 (species name, heat of formation) no2 0.34 n2 0.00 ... no 0.93 :pre Note that the species can be listed in any order. The tag that is used as the species name must correspond with the tags used to define the reactions with the "fix rx"_fix_rx.html command. Alternatively, corrections to the EOS can be included by specifying -three additional columns that correspond to the energy correction, -the temperature correction coefficient and molecule correction +three additional columns that correspond to the energy correction, +the temperature correction coefficient and molecule correction coefficient. In this case, the format of the file is as follows: # HEAT OF FORMATION TABLE (one or more comment or blank lines) :pre (blank) h2 0.00 1.23 0.025 0.0 (species name, heat of formation, energy correction, temperature correction coefficient, molecule correction coefficient) no2 0.34 0.00 0.000 -1.76 n2 0.00 0.00 0.000 -1.76 ... no 0.93 0.00 0.000 -1.76 :pre :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. The equation of state must be a monotonically increasing function. An error will occur if the internal temperature or internal energies are not within the table cutoffs. [Related commands:] "fix rx"_fix_rx.html, "pair dpd/fdt"_pair_dpd_fdt.html [Default:] none :line diff --git a/doc/src/fix_filter_corotate.txt b/doc/src/fix_filter_corotate.txt index a3339648f..b782d285c 100644 --- a/doc/src/fix_filter_corotate.txt +++ b/doc/src/fix_filter_corotate.txt @@ -1,87 +1,87 @@ "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 filter/corotate command :h3 [Syntax:] fix ID group-ID filter/corotate keyword value ... :pre ID, group-ID are documented in "fix"_fix.html command :ulb,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 :ule [Examples:] timestep 8 run_style respa 3 2 8 bond 1 pair 2 kspace 3 fix cor all filter/corotate m 1.0 :pre fix cor all filter/corotate b 4 19 a 3 5 2 :pre [Description:] This fix implements a corotational filter for a mollified impulse method. In biomolecular simulations, it allows the usage of larger timesteps for long-range electrostatic interactions. For details, see "(Fath)"_#Fath2017. When using "run_style respa"_run_style.html for a biomolecular simulation with high-frequency covalent bonds, the outer time-step is restricted to below ~ 4fs due to resonance problems. This fix filters the outer stage of the respa and thus a larger (outer) time-step can be used. Since in large biomolecular simulations the computation of the long-range electrostatic contributions poses a major bottleneck, this can significantly accelerate the simulation. The filter computes a cluster decomposition of the molecular structure following the criteria indicated by the options a, b, t and m. This process is similar to the approach in "fix shake"_fix_shake.html, however, the clusters are not kept contrained. Instead, the position is slightly modified only for the computation of long-range forces. A good cluster decomposition constitutes in building clusters which contain the fastest covalent bonds inside clusters. If the clusters are chosen suitably, the "run_style respa"_run_style.html is stable for outer time-steps of at least 8fs. :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:] -This fix is part of the USER-MISC package. It is only enabled if -LAMMPS was built with that package. See the "Making +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. Currently, it does not support "molecule templates"_molecule.html. [Related commands:] [Default:] none :line :link(Fath2017) [(Fath)] Fath, Hochbruck, Singh, J Comp Phys, 333, 180-198 (2017). diff --git a/doc/src/fix_gcmc.txt b/doc/src/fix_gcmc.txt index 7ac607a2f..41ec38cff 100644 --- a/doc/src/fix_gcmc.txt +++ b/doc/src/fix_gcmc.txt @@ -1,417 +1,417 @@ "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 gcmc command :h3 [Syntax:] fix ID group-ID gcmc N X M type seed T mu displace keyword values ... :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l gcmc = style name of this fix command :l N = invoke this fix every N steps :l X = average number of GCMC exchanges to attempt every N steps :l M = average number of MC moves to attempt every N steps :l type = atom type for inserted atoms (must be 0 if mol keyword used) :l seed = random # seed (positive integer) :l T = temperature of the ideal gas reservoir (temperature units) :l mu = chemical potential of the ideal gas reservoir (energy units) :l displace = maximum Monte Carlo translation distance (length units) :l zero or more keyword/value pairs may be appended to args :l keyword = {mol}, {region}, {maxangle}, {pressure}, {fugacity_coeff}, {full_energy}, {charge}, {group}, {grouptype}, {intra_energy}, {tfac_insert}, or {overlap_cutoff} {mol} value = template-ID template-ID = ID of molecule template specified in a separate "molecule"_molecule.html command {rigid} value = fix-ID fix-ID = ID of "fix rigid/small"_fix_rigid.html command {shake} value = fix-ID fix-ID = ID of "fix shake"_fix_shake.html command {region} value = region-ID region-ID = ID of region where MC moves are allowed {maxangle} value = maximum molecular rotation angle (degrees) {pressure} value = pressure of the gas reservoir (pressure units) {fugacity_coeff} value = fugacity coefficient of the gas reservoir (unitless) {full_energy} = compute the entire system energy when performing MC moves {charge} value = charge of inserted atoms (charge units) {group} value = group-ID group-ID = group-ID for inserted atoms (string) {grouptype} values = type group-ID type = atom type (int) group-ID = group-ID for inserted atoms (string) {intra_energy} value = intramolecular energy (energy units) {tfac_insert} value = scale up/down temperature of inserted atoms (unitless) {overlap_cutoff} value = maximum pair distance for overlap rejection (distance units) :pre :ule [Examples:] fix 2 gas gcmc 10 1000 1000 2 29494 298.0 -0.5 0.01 fix 3 water gcmc 10 100 100 0 3456543 3.0 -2.5 0.1 mol my_one_water maxangle 180 full_energy fix 4 my_gas gcmc 1 10 10 1 123456543 300.0 -12.5 1.0 region disk :pre [Description:] This fix performs grand canonical Monte Carlo (GCMC) exchanges of atoms or molecules of the given type with an imaginary ideal gas reservoir at the specified T and chemical potential (mu) as discussed in "(Frenkel)"_#Frenkel. If used with the "fix nvt"_fix_nh.html command, simulations in the grand canonical ensemble (muVT, constant chemical potential, constant volume, and constant temperature) can be performed. Specific uses include computing isotherms in microporous materials, or computing vapor-liquid coexistence curves. Every N timesteps the fix attempts a number of GCMC exchanges (insertions or deletions) of gas atoms or molecules of the given type between the simulation cell and the imaginary reservoir. It also attempts a number of Monte Carlo moves (translations and molecule rotations) of gas of the given type within the simulation cell or region. The average number of attempted GCMC exchanges is X. The average number of attempted MC moves is M. M should typically be chosen to be approximately equal to the expected number of gas atoms or molecules of the given type within the simulation cell or region, which will result in roughly one MC translation per atom or molecule per MC cycle. For MC moves of molecular gasses, rotations and translations are each attempted with 50% probability. For MC moves of atomic gasses, translations are attempted 100% of the time. For MC exchanges of either molecular or atomic gasses, deletions and insertions are each attempted with 50% probability. All inserted particles are always assigned to two groups: the default group "all" and the group specified in the fix gcmc command (which can also be "all"). In addition, particles are also added to any groups specified by the {group} and {grouptype} keywords. If inserted particles are individual atoms, they are assigned the atom type given by the type argument. If they are molecules, the type argument has no effect and must be set to zero. Instead, the type of each atom in the inserted molecule is specified in the file read by the "molecule"_molecule.html command. This fix cannot be used to perform MC insertions of gas atoms or molecules other than the exchanged type, but MC deletions, translations, and rotations can be performed on any atom/molecule in the fix group. All atoms in the simulation cell can be moved using regular time integration translations, e.g. via "fix nvt"_fix_nh.html, resulting in a hybrid GCMC+MD simulation. A smaller-than-usual timestep size may be needed when running such a hybrid simulation, especially if the inserted molecules are not well equilibrated. This command may optionally use the {region} keyword to define an exchange and move volume. The specified region must have been previously defined with a "region"_region.html command. It must be defined with side = {in}. Insertion attempts occur only within the specified region. For non-rectangular regions, random trial points are generated within the rectangular bounding box until a point is found that lies inside the region. If no valid point is generated after 1000 trials, no insertion is performed, but it is counted as an attempted insertion. Move and deletion attempt candidates are selected from gas atoms or molecules within the region. If there are no candidates, no move or deletion is performed, but it is counted as an attempt move or deletion. If an attempted move places the atom or molecule center-of-mass outside the specified region, a new attempted move is generated. This process is repeated until the atom or molecule center-of-mass is inside the specified region. If used with "fix nvt"_fix_nh.html, the temperature of the imaginary reservoir, T, should be set to be equivalent to the target temperature used in fix nvt. Otherwise, the imaginary reservoir will not be in thermal equilibrium with the simulation cell. Also, it is important that the temperature used by fix nvt be dynamic/dof, which can be achieved as follows: compute mdtemp mdatoms temp compute_modify mdtemp dynamic/dof yes fix mdnvt mdatoms nvt temp 300.0 300.0 10.0 fix_modify mdnvt temp mdtemp :pre Note that neighbor lists are re-built every timestep that this fix is invoked, so you should not set N to be too small. However, periodic rebuilds are necessary in order to avoid dangerous rebuilds and missed interactions. Specifically, avoid performing so many MC translations per timestep that atoms can move beyond the neighbor list skin distance. See the "neighbor"_neighbor.html command for details. When an atom or molecule is to be inserted, its coordinates are chosen at a random position within the current simulation cell or region, and new atom velocities are randomly chosen from the specified temperature distribution given by T. The effective temperature for new atom velocities can be increased or decreased using the optional keyword {tfac_insert} (see below). Relative coordinates for atoms in a molecule are taken from the template molecule provided by the user. The center of mass of the molecule is placed at the insertion point. The orientation of the molecule is chosen at random by rotating about this point. Individual atoms are inserted, 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. When not using the {mol} keyword, you should ensure you do not delete atoms that are bonded to other atoms, or LAMMPS will soon generate an error when it tries to find bonded neighbors. LAMMPS will warn you if any of the atoms eligible for deletion have a non-zero molecule ID, but does not check for this at the time of deletion. If you wish to insert molecules via the {mol} keyword, that will be treated as rigid bodies, use the {rigid} keyword, specifying as its value the ID of a separate "fix rigid/small"_fix_rigid.html command which also appears in your input script. NOTE: If you wish the new rigid molecules (and other rigid molecules) to be thermostatted correctly via "fix rigid/small/nvt"_fix_rigid.html or "fix rigid/small/npt"_fix_rigid.html, then you need to use the "fix_modify dynamic/dof yes" command for the rigid fix. This is to inform that fix that the molecule count will vary dynamically. If you wish to insert molecules via the {mol} keyword, that will have their bonds or angles constrained via SHAKE, use the {shake} keyword, specifying as its value the ID of a separate "fix shake"_fix_shake.html command which also appears in your input script. Optionally, users may specify the maximum rotation angle for molecular rotations using the {maxangle} keyword and specifying the angle in degrees. Rotations are performed by generating a random point on the unit sphere and a random rotation angle on the range \[0,maxangle). The molecule is then rotated by that angle about an axis passing through the molecule center of mass. The axis is parallel to the unit vector defined by the point on the unit sphere. The same procedure is used for randomly rotating molecules when they are inserted, except that the maximum angle is 360 degrees. Note that fix GCMC does not use configurational bias MC or any other kind of sampling of intramolecular degrees of freedom. Inserted molecules can have different orientations, but they will all have the same intramolecular configuration, which was specified in the molecule command input. For atomic gasses, inserted atoms have the specified atom type, but deleted atoms are any atoms that have been inserted or that belong to the user-specified fix group. For molecular gasses, exchanged molecules use the same atom types as in the template molecule supplied by the user. In both cases, exchanged atoms/molecules are assigned to two groups: the default group "all" and the group specified in the fix gcmc command (which can also be "all"). The chemical potential is a user-specified input parameter defined as: :c,image(Eqs/fix_gcmc1.jpg) The second term mu_ex is the excess chemical potential due to energetic interactions and is formally zero for the fictitious gas reservoir but is non-zero for interacting systems. So, while the chemical potential of the reservoir and the simulation cell are equal, mu_ex is not, and as a result, the densities of the two are generally quite different. The first term mu_id is the ideal gas contribution to the chemical potential. mu_id can be related to the density or pressure of the fictitious gas reservoir by: :c,image(Eqs/fix_gcmc2.jpg) where k is Boltzman's constant, T is the user-specified temperature, rho is the number density, P is the pressure, and phi is the fugacity coefficient. The constant Lambda is required for dimensional consistency. For all unit styles except {lj} it is defined as the thermal de Broglie wavelength :c,image(Eqs/fix_gcmc3.jpg) where h is Planck's constant, and m is the mass of the exchanged atom or molecule. For unit style {lj}, Lambda is simply set to the unity. Note that prior to March 2017, lambda for unit style {lj} was calculated using the above formula with h set to the rather specific value of 0.18292026. Chemical potential under the old definition can be converted to an equivalent value under the new definition by subtracting 3kTln(Lambda_old). As an alternative to specifying mu directly, the ideal gas reservoir can be defined by its pressure P using the {pressure} keyword, in which case the user-specified chemical potential is ignored. The user may also specify the fugacity coefficient phi using the {fugacity_coeff} keyword, which defaults to unity. The {full_energy} option means that fix GCMC will compute the total potential energy of the entire simulated system. The total system energy before and after the proposed GCMC move is then used in the Metropolis criterion to determine whether or not to accept the proposed GCMC move. By default, this option is off, in which case only partial energies are computed to determine the difference in energy that would be caused by the proposed GCMC move. The {full_energy} option is needed for systems with complicated potential energy calculations, including the following: long-range electrostatics (kspace) many-body pair styles hybrid pair styles eam pair styles tail corrections need to include potential energy contributions from other fixes :ul In these cases, LAMMPS will automatically apply the {full_energy} keyword and issue a warning message. When the {mol} keyword is used, the {full_energy} option also includes the intramolecular energy of inserted and deleted molecules. If this is not desired, the {intra_energy} keyword can be used to define an amount of energy that is subtracted from the final energy when a molecule is inserted, and added to the initial energy when a molecule is deleted. For molecules that have a non-zero intramolecular energy, this will ensure roughly the same behavior whether or not the {full_energy} option is used. Inserted atoms and molecules are assigned random velocities based on the specified temperature T. Because the relative velocity of all atoms in the molecule is zero, this may result in inserted molecules that are systematically too cold. In addition, the intramolecular potential energy of the inserted molecule may cause the kinetic energy of the molecule to quickly increase or decrease after insertion. The {tfac_insert} keyword allows the user to counteract these effects by changing the temperature used to assign velocities to inserted atoms and molecules by a constant factor. For a particular application, some experimentation may be required to find a value of {tfac_insert} that results in inserted molecules that equilibrate quickly to the correct temperature. Some fixes have an associated potential energy. Examples of such fixes include: "efield"_fix_efield.html, "gravity"_fix_gravity.html, "addforce"_fix_addforce.html, "langevin"_fix_langevin.html, "restrain"_fix_restrain.html, "temp/berendsen"_fix_temp_berendsen.html, "temp/rescale"_fix_temp_rescale.html, and "wall fixes"_fix_wall.html. For that energy to be included in the total potential energy of the system (the quantity used when performing GCMC moves), you MUST enable the "fix_modify"_fix_modify.html {energy} option for that fix. The doc pages for individual "fix"_fix.html commands specify if this should be done. Use the {charge} option to insert atoms with a user-specified point charge. Note that doing so will cause the system to become non-neutral. LAMMPS issues a warning when using long-range electrostatics (kspace) with non-neutral systems. See the "compute group/group"_compute_group_group.html documentation for more details about simulating non-neutral systems with kspace on. Use of this fix typically will cause the number of atoms to fluctuate, therefore, you will want to use the "compute_modify"_compute_modify.html command to insure that the current number of atoms is used as a normalizing factor each time temperature is computed. Here is the necessary command: NOTE: If the density of the cell is initially very small or zero, and increases to a much larger density after a period of equilibration, then certain quantities that are only calculated once at the start (kspace parameters, tail corrections) may no longer be accurate. The solution is to start a new simulation after the equilibrium density has been reached. With some pair_styles, such as "Buckingham"_pair_buck.html, "Born-Mayer-Huggins"_pair_born.html and "ReaxFF"_pair_reaxc.html, two atoms placed close to each other may have an arbitrary large, negative potential energy due to the functional form of the potential. While these unphysical configurations are inaccessible to typical dynamical trajectories, they can be generated by Monte Carlo moves. The {overlap_cutoff} keyword suppresses these moves by effectively assigning an infinite positive energy to all new configurations that place any pair of atoms closer than the specified overlap cutoff distance. compute_modify thermo_temp dynamic yes :pre If LJ units are used, note that a value of 0.18292026 is used by this fix as the reduced value for Planck's constant. This value was derived from LJ parameters for argon, where h* = h/sqrt(sigma^2 * epsilon * mass), sigma = 3.429 angstroms, epsilon/k = 121.85 K, and mass = 39.948 amu. The {group} keyword assigns all inserted atoms to the "group"_group.html of the group-ID value. The {grouptype} keyword assigns all inserted atoms of the specified type to the "group"_group.html of the group-ID value. [Restart, fix_modify, output, run start/stop, minimize info:] This fix writes the state of the fix to "binary restart files"_restart.html. This includes information about the random number generator seed, the next timestep for MC exchanges, etc. 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. This fix computes a global vector of length 8, which can be accessed by various "output commands"_Section_howto.html#howto_15. The vector values are the following global cumulative quantities: 1 = translation attempts 2 = translation successes 3 = insertion attempts 4 = insertion successes 5 = deletion attempts 6 = deletion successes 7 = rotation attempts 8 = rotation successes :ul The 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. This fix is not invoked during "energy minimization"_minimize.html. [Restrictions:] This fix is part of the MC 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. Do not set "neigh_modify once yes" or else this fix will never be called. Reneighboring is required. Can be run in parallel, but aspects of the GCMC part will not scale well in parallel. Only usable for 3D simulations. Note that very lengthy simulations involving insertions/deletions of billions of gas molecules may run out of atom or molecule IDs and trigger an error, so it is better to run multiple shorter-duration simulations. Likewise, very large molecules have not been tested and may turn out to be problematic. Use of multiple fix gcmc commands in the same input script can be problematic if using a template molecule. The issue is that the user-referenced template molecule in the second fix gcmc command may no longer exist since it might have been deleted by the first fix gcmc command. An existing template molecule will need to be referenced by the user for each subsequent fix gcmc command. [Related commands:] "fix atom/swap"_fix_atom_swap.html, "fix nvt"_fix_nh.html, "neighbor"_neighbor.html, "fix deposit"_fix_deposit.html, "fix evaporate"_fix_evaporate.html, "delete_atoms"_delete_atoms.html [Default:] The option defaults are mol = no, maxangle = 10, overlap_cutoff = 0.0, -fugacity_coeff = 1, and full_energy = no, +fugacity_coeff = 1, and full_energy = no, except for the situations where full_energy is required, as listed above. :line :link(Frenkel) [(Frenkel)] Frenkel and Smit, Understanding Molecular Simulation, Academic Press, London, 2002. diff --git a/doc/src/fix_grem.txt b/doc/src/fix_grem.txt index 3fc5c1a10..661f68ed9 100644 --- a/doc/src/fix_grem.txt +++ b/doc/src/fix_grem.txt @@ -1,111 +1,111 @@ "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 grem command :h3 [Syntax:] fix ID group-ID grem lambda eta H0 thermostat-ID :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l grem = style name of this fix command :l lambda = intercept parameter of linear effective temperature function :l eta = slope parameter of linear effective temperature function :l H0 = shift parameter of linear effective temperature function :l thermostat-ID = ID of Nose-Hoover thermostat or barostat used in simulation :l,ule [Examples:] fix fxgREM all grem 400 -0.01 -30000 fxnpt thermo_modify press fxgREM_press :pre fix fxgREM all grem 502 -0.15 -80000 fxnvt :pre [Description:] This fix implements the molecular dynamics version of the generalized replica exchange method (gREM) originally developed by "(Kim)"_#Kim2010, which uses non-Boltzmann ensembles to sample over first order phase transitions. The is done by defining replicas with an enthalpy dependent effective temperature :c,image(Eqs/fix_grem.jpg) with {eta} negative and steep enough to only intersect the characteristic microcanonical temperature (Ts) of the system once, ensuring a unimodal enthalpy distribution in that replica. {Lambda} is the intercept and effects the generalized ensemble similar to how temperature effects a Boltzmann ensemble. {H0} is a reference enthalpy, and is typically set as the lowest desired sampled enthalpy. Further explanation can be found in our recent papers "(Malolepsza)"_#Malolepsza. This fix requires a Nose-Hoover thermostat fix reference passed to the grem as {thermostat-ID}. Two distinct temperatures exist in this generalized ensemble, the effective temperature defined above, and a kinetic temperature that controls the velocity distribution of particles as usual. Either constant volume or constant pressure algorithms can be used. The fix enforces a generalized ensemble in a single replica only. Typically, this ideaology is combined with replica exchange with replicas differing by {lambda} only for simplicity, but this is not required. A multi-replica simulation can be run within the LAMMPS environment using the "temper/grem"_temper_grem.html command. This utilizes LAMMPS partition mode and requires the number of available processors be on the order of the number of desired replicas. A 100-replica simulation would require at least 100 processors (1 per world at minimum). If a many replicas are needed on a small number of processors, multi-replica runs can be run outside of LAMMPS. An example of this can be found in examples/USER/misc/grem and has no limit on the number of replicas per processor. However, this is very inefficient and error prone and should be avoided if possible. In general, defining the generalized ensembles is unique for every system. When starting a many-replica simulation without any knowledge of the underlying microcanonical temperature, there are several tricks we have utilized to optimize the process. Choosing a less-steep {eta} yields broader distributions, requiring fewer replicas to map the microcanonical temperature. While this likely struggles from the same sampling problems gREM was built to avoid, it provides quick insight to Ts. Initially using an evenly-spaced {lambda} distribution identifies regions where small changes in enthalpy lead to large temperature changes. Replicas are easily added where needed. :line [Restart, fix_modify, output, run start/stop, minimize info:] No information about this fix is written to "binary restart files"_restart.html. The "thermo_modify"_thermo_modify.html {press} option is supported -by this fix to add the rescaled kinetic pressure as part of +by this fix to add the rescaled kinetic pressure as part of "thermodynamic output"_thermo_style.html. [Restrictions:] -This fix is part of the USER-MISC package. It is only enabled if -LAMMPS was built with that package. See the "Making +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. [Related commands:] "temper/grem"_temper_grem.html, "fix nvt"_fix_nh.html, "fix npt"_fix_nh.html, "thermo_modify"_thermo_modify.html [Default:] none :line :link(Kim2010) [(Kim)] Kim, Keyes, Straub, J Chem. Phys, 132, 224107 (2010). :link(Malolepsza) [(Malolepsza)] Malolepsza, Secor, Keyes, J Phys Chem B 119 (42), 13379-13384 (2015). diff --git a/doc/src/fix_ipi.txt b/doc/src/fix_ipi.txt index b1533830b..07e8025d7 100644 --- a/doc/src/fix_ipi.txt +++ b/doc/src/fix_ipi.txt @@ -1,101 +1,101 @@ "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 ipi command :h3 [Syntax:] fix ID group-ID ipi address port \[unix\] \[reset\] :pre ID, group-ID are documented in "fix"_fix.html command ipi = style name of this fix command address = internet address (FQDN or IP), or UNIX socket name port = port number (ignored for UNIX sockets) optional keyword = {unix}, if present uses a unix socket optional keyword = {reset}, if present reset electrostatics at each call :ul [Examples:] fix 1 all ipi my.server.com 12345 fix 1 all ipi mysocket 666 unix reset [Description:] This fix enables LAMMPS to be run as a client for the i-PI Python wrapper "(IPI)"_#ipihome for performing a path integral molecular dynamics (PIMD) simulation. The philosophy behind i-PI is described in the following publication "(IPI-CPC)"_#IPICPC. A version of the i-PI package, containing only files needed for use with LAMMPS, is provided in the tools/i-pi directory. See the tools/i-pi/manual.pdf for an introduction to i-PI. The examples/USER/i-pi directory contains example scripts for using i-PI with LAMMPS. In brief, the path integral molecular dynamics is performed by the Python wrapper, while the client (LAMMPS in this case) simply computes forces and energy for each configuration. The communication between the two components takes place using sockets, and is reduced to the bare minimum. All the parameters of the dynamics are specified in the input of i-PI, and all the parameters of the force field must be specified as LAMMPS inputs, preceding the {fix ipi} command. The server address must be specified by the {address} argument, and can be either the IP address, the fully-qualified name of the server, or the name of a UNIX socket for local, faster communication. In the case of internet sockets, the {port} argument specifies the port number on which i-PI is listening, while the {unix} optional switch specifies that the socket is a UNIX socket. Note that there is no check of data integrity, or that the atomic configurations make sense. It is assumed that the species in the i-PI input are listed in the same order as in the data file of LAMMPS. The initial configuration is ignored, as it will be substituted with the coordinates received from i-PI before forces are ever evaluated. -A note of caution when using potentials that contain long-range +A note of caution when using potentials that contain long-range electrostatics, or that contain parameters that depend on box size: all of these options will be initialized based on the cell size in the -LAMMPS-side initial configuration and kept constant during the run. -This is required to e.g. obtain reproducible and conserved forces. -If the cell varies too wildly, it may be advisable to reinitialize -these interactions at each call. This behavior can be requested by -setting the {reset} switch. +LAMMPS-side initial configuration and kept constant during the run. +This is required to e.g. obtain reproducible and conserved forces. +If the cell varies too wildly, it may be advisable to reinitialize +these interactions at each call. This behavior can be requested by +setting the {reset} switch. [Restart, fix_modify, output, run start/stop, minimize info:] There is no restart information associated with this fix, since all the dynamical parameters are dealt with by i-PI. [Restrictions:] Using this fix on anything other than all atoms requires particular care, since i-PI will know nothing on atoms that are not those whose coordinates are transferred. However, one could use this strategy to define an external potential acting on the atoms that are moved by i-PI. 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. Because of the use of UNIX domain sockets, this fix will only work in a UNIX environment. [Related commands:] "fix nve"_fix_nve.html :line :link(IPICPC) [(IPI-CPC)] Ceriotti, More and Manolopoulos, Comp Phys Comm, 185, 1019-1026 (2014). :link(ipihome) [(IPI)] "http://epfl-cosmo.github.io/gle4md/index.html?page=ipi"_http://epfl-cosmo.github.io/gle4md/index.html?page=ipi diff --git a/doc/src/fix_mscg.txt b/doc/src/fix_mscg.txt index 0e09f8a9c..7d1696795 100644 --- a/doc/src/fix_mscg.txt +++ b/doc/src/fix_mscg.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 fix mscg command :h3 [Syntax:] fix ID group-ID mscg N keyword args ... :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l mscg = style name of this fix command :l N = envoke this fix every this many timesteps :l zero or more keyword/value pairs may be appended :l keyword = {range} or {name} or {max} :l {range} arg = {on} or {off} {on} = range finding functionality is performed {off} = force matching functionality is performed {name} args = name1 ... nameN name1,...,nameN = string names for each atom type (1-Ntype) {max} args = maxb maxa maxd maxb,maxa,maxd = maximum bonds/angles/dihedrals per atom :pre :ule [Examples:] fix 1 all mscg 1 fix 1 all mscg 1 range name A B fix 1 all mscg 1 max 4 8 20 :pre [Description:] This fix applies the Multi-Scale Coarse-Graining (MSCG) method to snapshots from a dump file to generate potentials for coarse-grained simulations from all-atom simulations, using a force-matching technique ("Izvekov"_#Izvekov, "Noid"_#Noid). It makes use of the MS-CG library, written and maintained by Greg Voth's group at the University of Chicago, which is freely available on their "MS-CG GitHub site"_https://github.com/uchicago-voth/MSCG-release. See instructions on obtaining and installing the MS-CG library in the src/MSCG/README file, which must be done before you build LAMMPS with this fix command and use the command in a LAMMPS input script. An example script using this fix is provided the examples/mscg directory. The general workflow for using LAMMPS in conjunction with the MS-CG library to create a coarse-grained model and run coarse-grained simulations is as follows: Perform all-atom simulations on the system to be coarse grained. Generate a trajectory mapped to the coarse-grained model. Create input files for the MS-CG library. -Run the range finder functionality of the MS-CG library. +Run the range finder functionality of the MS-CG library. Run the force matching functionality of the MS-CG library. Check the results of the force matching. Run coarse-grained simulations using the new coarse-grained potentials. :ol This fix can perform the range finding and force matching steps 4 and 5 of the above workflow when used in conjunction with the "rerun"_rerun.html command. It does not perform steps 1-3 and 6-7. Step 2 can be performed using a Python script (what is the name?) provided with the MS-CG library which defines the coarse-grained model and converts a standard LAMMPS dump file for an all-atom simulation (step 1) into a LAMMPS dump file which has the positions of and forces -on the coarse-grained beads. +on the coarse-grained beads. In step 3, an input file named "control.in" is needed by the MS-CG library which sets parameters for the range finding and force matching functionalities. See the examples/mscg/control.in file as an example. And see the documentation provided with the MS-CG library for more info on this file. When this fix is used to perform steps 4 and 5, the MS-CG library also produces additional output files. The range finder functionality (step 4) outputs files defining pair and bonded interaction ranges. The force matching functionality (step 5) outputs tabulated force files for every interaction in the system. Other diagnostic files can also be output depending on the parameters in the MS-CG library input script. Again, see the documentation provided with the MS-CG library for more info. :line The {range} keyword specifies which MS-CG library functionality should be invoked. If {on}, the step 4 range finder functionality is invoked. {off}, the step 5 force matching functionality is invoked. If the {name} keyword is used, string names are defined to associate with the integer atom types in LAMMPS. {Ntype} names must be provided, one for each atom type (1-Ntype). The {max} keyword specifies the maximum number of bonds, angles, and dihedrals a bead can have in the coarse-grained model. [Restrictions:] This fix is part of the MSCG 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 MS-CG library uses C++11, which may not be supported by older compilers. The MS-CG library also has some additional numeric library dependencies, which are described in its documentation. Currently, the MS-CG library is not setup to run in parallel with MPI, so this fix can only be used in a serial LAMMPS build and run on a single processor. [Related commands:] none [Default:] The default keyword settings are range off, max 4 12 36. :line :link(Izvekov) [(Izvekov)] Izvekov, Voth, J Chem Phys 123, 134105 (2005). :link(Noid) [(Noid)] Noid, Chu, Ayton, Krishna, Izvekov, Voth, Das, Andersen, J Chem Phys 128, 134105 (2008). diff --git a/doc/src/fix_nve_dot.txt b/doc/src/fix_nve_dot.txt index b1c00cd25..7ad51f376 100644 --- a/doc/src/fix_nve_dot.txt +++ b/doc/src/fix_nve_dot.txt @@ -1,61 +1,61 @@ "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 nve/dot command :h3 [Syntax:] fix ID group-ID nve/dot :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l nve/dot = style name of this fix command :l :ule [Examples:] fix 1 all nve/dot :pre [Description:] Apply a rigid-body integrator as described in "(Davidchack)"_#Davidchack1 -to a group of atoms, but without Langevin dynamics. +to a group of atoms, but without Langevin dynamics. This command performs Molecular dynamics (MD) -via a velocity-Verlet algorithm and an evolution operator that rotates -the quaternion degrees of freedom, similar to the scheme outlined in "(Miller)"_#Miller1. +via a velocity-Verlet algorithm and an evolution operator that rotates +the quaternion degrees of freedom, similar to the scheme outlined in "(Miller)"_#Miller1. This command is the equivalent of the "fix nve/dotc/langevin"_fix_nve_dotc_langevin.html -without damping and noise and can be used to determine the stability range +without damping and noise and can be used to determine the stability range in a NVE ensemble prior to using the Langevin-type DOTC-integrator (see also "fix nve/dotc/langevin"_fix_nve_dotc_langevin.html). The command is equivalent to the "fix nve"_fix_nve.html. The particles are always considered to have a finite size. An example input file can be found in /examples/USER/cgdna/examples/duplex1/. A technical report with more information on this integrator can be found "here"_PDF/USER-CGDNA-overview.pdf. :line [Restrictions:] These pair styles can only be used if LAMMPS was built with the USER-CGDNA package and the MOLECULE and ASPHERE package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info on packages. [Related commands:] "fix nve/dotc/langevin"_fix_nve_dotc_langevin.html, "fix nve"_fix_nve.html [Default:] none :line :link(Davidchack1) [(Davidchack)] R.L Davidchack, T.E. Ouldridge, and M.V. Tretyakov. J. Chem. Phys. 142, 144114 (2015). :link(Miller1) [(Miller)] T. F. Miller III, M. Eleftheriou, P. Pattnaik, A. Ndirango, G. J. Martyna, J. Chem. Phys., 116, 8649-8659 (2002). diff --git a/doc/src/fix_nve_dotc_langevin.txt b/doc/src/fix_nve_dotc_langevin.txt index 19d5b233c..5de8e663c 100644 --- a/doc/src/fix_nve_dotc_langevin.txt +++ b/doc/src/fix_nve_dotc_langevin.txt @@ -1,134 +1,134 @@ "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 nve/dotc/langevin command :h3 [Syntax:] fix ID group-ID nve/dotc/langevin Tstart Tstop damp seed keyword value :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l nve/dotc/langevin = style name of this fix command :l Tstart,Tstop = desired temperature at start/end of run (temperature units) :l damp = damping parameter (time units) :l seed = random number seed to use for white noise (positive integer) :l keyword = {angmom} :l {angmom} value = factor factor = do thermostat rotational degrees of freedom via the angular momentum and apply numeric scale factor as discussed below :pre :ule [Examples:] fix 1 all nve/dotc/langevin 1.0 1.0 0.03 457145 angmom 10 :pre [Description:] -Apply a rigid-body Langevin-type integrator of the kind "Langevin C" +Apply a rigid-body Langevin-type integrator of the kind "Langevin C" as described in "(Davidchack)"_#Davidchack2 to a group of atoms, which models an interaction with an implicit background solvent. This command performs Brownian dynamics (BD) -via a technique that splits the integration into a deterministic Hamiltonian -part and the Ornstein-Uhlenbeck process for noise and damping. +via a technique that splits the integration into a deterministic Hamiltonian +part and the Ornstein-Uhlenbeck process for noise and damping. The quaternion degrees of freedom are updated though an evolution operator which performs a rotation in quaternion space, preserves the quaternion norm and is akin to "(Miller)"_#Miller2. -In terms of syntax this command has been closely modelled on the -"fix langevin"_fix_langevin.html and its {angmom} option. But it combines -the "fix nve"_fix_nve.html and the "fix langevin"_fix_langevin.html in -one single command. The main feature is improved stability +In terms of syntax this command has been closely modelled on the +"fix langevin"_fix_langevin.html and its {angmom} option. But it combines +the "fix nve"_fix_nve.html and the "fix langevin"_fix_langevin.html in +one single command. The main feature is improved stability over the standard integrator, permitting slightly larger timestep sizes. NOTE: Unlike the "fix langevin"_fix_langevin.html this command performs also time integration of the translational and quaternion degrees of freedom. The total force on each atom will have the form: F = Fc + Ff + Fr Ff = - (m / damp) v Fr is proportional to sqrt(Kb T m / (dt damp)) :pre Fc is the conservative force computed via the usual inter-particle interactions ("pair_style"_pair_style.html, "bond_style"_bond_style.html, etc). -The Ff and Fr terms are implicitly taken into account by this fix +The Ff and Fr terms are implicitly taken into account by this fix on a per-particle basis. Ff is a frictional drag or viscous damping term proportional to the particle's velocity. The proportionality constant for each atom is computed as m/damp, where m is the mass of the particle and damp is the damping factor specified by the user. Fr is a force due to solvent atoms at a temperature T randomly bumping into the particle. As derived from the fluctuation/dissipation theorem, its magnitude as shown above is proportional to sqrt(Kb T m / dt damp), where Kb is the Boltzmann constant, T is the desired temperature, m is the mass of the particle, dt is the timestep size, and damp is the damping factor. Random numbers are used to randomize the direction and magnitude of this force as described in "(Dunweg)"_#Dunweg3, where a uniform random number is used (instead of a Gaussian random number) for speed. :line -{Tstart} and {Tstop} have to be constant values, i.e. they cannot +{Tstart} and {Tstop} have to be constant values, i.e. they cannot be variables. The {damp} parameter is specified in time units and determines how rapidly the temperature is relaxed. For example, a value of 0.03 means to relax the temperature in a timespan of (roughly) 0.03 time units tau (see the "units"_units.html command). The damp factor can be thought of as inversely related to the viscosity of the solvent, i.e. a small relaxation time implies a hi-viscosity solvent and vice versa. See the discussion about gamma and viscosity in the documentation for the "fix viscous"_fix_viscous.html command for more details. The random # {seed} must be a positive integer. A Marsaglia random number generator is used. Each processor uses the input seed to generate its own unique seed and its own stream of random numbers. Thus the dynamics of the system will not be identical on two runs on different numbers of processors. The keyword/value option has to be used in the following way: -This fix has to be used together with the {angmom} keyword. The -particles are always considered to have a finite size. -The keyword {angmom} enables thermostatting of the rotational degrees of -freedom in addition to the usual translational degrees of freedom. +This fix has to be used together with the {angmom} keyword. The +particles are always considered to have a finite size. +The keyword {angmom} enables thermostatting of the rotational degrees of +freedom in addition to the usual translational degrees of freedom. -The scale factor after the {angmom} keyword gives the ratio of the rotational to +The scale factor after the {angmom} keyword gives the ratio of the rotational to the translational friction coefficient. An example input file can be found in /examples/USER/cgdna/examples/duplex2/. -A technical report with more information on this integrator can be found +A technical report with more information on this integrator can be found "here"_PDF/USER-CGDNA-overview.pdf. :line [Restrictions:] These pair styles can only be used if LAMMPS was built with the USER-CGDNA package and the MOLECULE and ASPHERE package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info on packages. [Related commands:] -"fix nve"_fix_nve.html, "fix langevin"_fix_langevin.html, "fix nve/dot"_fix_nve_dot.html, +"fix nve"_fix_nve.html, "fix langevin"_fix_langevin.html, "fix nve/dot"_fix_nve_dot.html, [Default:] none :line :link(Davidchack2) [(Davidchack)] R.L Davidchack, T.E. Ouldridge, M.V. Tretyakov. J. Chem. Phys. 142, 144114 (2015). :link(Miller2) [(Miller)] T. F. Miller III, M. Eleftheriou, P. Pattnaik, A. Ndirango, G. J. Martyna, J. Chem. Phys., 116, 8649-8659 (2002). :link(Dunweg3) [(Dunweg)] B. Dunweg, W. Paul, Int. J. Mod. Phys. C, 2, 817-27 (1991). diff --git a/doc/src/fix_nvk.txt b/doc/src/fix_nvk.txt index 271483b44..49fd8217a 100644 --- a/doc/src/fix_nvk.txt +++ b/doc/src/fix_nvk.txt @@ -1,71 +1,71 @@ "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 nvk command :h3 [Syntax:] fix ID group-ID nvk :pre ID, group-ID are documented in "fix"_fix.html command nvk = style name of this fix command :ul [Examples:] fix 1 all nvk :pre [Description:] Perform constant kinetic energy integration using the Gaussian thermostat to update position and velocity for atoms in the group each timestep. V is volume; K is kinetic energy. This creates a system trajectory consistent with the isokinetic ensemble. The equations of motion used are those of Minary et al in -"(Minary)"_#nvk-Minary, a variant of those initially given by Zhang in +"(Minary)"_#nvk-Minary, a variant of those initially given by Zhang in "(Zhang)"_#nvk-Zhang. The kinetic energy will be held constant at its value given when fix nvk is initiated. If a different kinetic energy is desired, the "velocity"_velocity.html command should be used to change the kinetic energy prior to this fix. :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. 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:] The Gaussian thermostat only works when it is applied to all atoms in the simulation box. Therefore, the group must be set to all. This fix has not yet been implemented to work with the RESPA integrator. 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. [Related commands:] none [Default:] none :line :link(nvk-Minary) [(Minary)] Minary, Martyna, and Tuckerman, J Chem Phys, 18, 2510 (2003). :link(nvk-Zhang) [(Zhang)] Zhang, J Chem Phys, 106, 6102 (1997). diff --git a/doc/src/fix_spring.txt b/doc/src/fix_spring.txt index 5f94f4cda..014a43aac 100644 --- a/doc/src/fix_spring.txt +++ b/doc/src/fix_spring.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 fix spring command :h3 [Syntax:] fix ID group-ID spring keyword values :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l spring = style name of this fix command :l keyword = {tether} or {couple} :l {tether} values = K x y z R0 K = spring constant (force/distance units) x,y,z = point to which spring is tethered R0 = equilibrium distance from tether point (distance units) {couple} values = group-ID2 K x y z R0 group-ID2 = 2nd group to couple to fix group with a spring K = spring constant (force/distance units) x,y,z = direction of spring R0 = equilibrium distance of spring (distance units) :pre :ule [Examples:] fix pull ligand spring tether 50.0 0.0 0.0 0.0 0.0 fix pull ligand spring tether 50.0 0.0 0.0 0.0 5.0 fix pull ligand spring tether 50.0 NULL NULL 2.0 3.0 fix 5 bilayer1 spring couple bilayer2 100.0 NULL NULL 10.0 0.0 fix longitudinal pore spring couple ion 100.0 NULL NULL -20.0 0.0 fix radial pore spring couple ion 100.0 0.0 0.0 NULL 5.0 :pre [Description:] Apply a spring force to a group of atoms or between two groups of atoms. This is useful for applying an umbrella force to a small molecule or lightly tethering a large group of atoms (e.g. all the solvent or a large molecule) to the center of the simulation box so that it doesn't wander away over the course of a long simulation. It can also be used to hold the centers of mass of two groups of atoms at a given distance or orientation with respect to each other. The {tether} style attaches a spring between a fixed point {x,y,z} and the center of mass of the fix group of atoms. The equilibrium position of the spring is R0. At each timestep the distance R from the center of mass of the group of atoms to the tethering point is computed, taking account of wrap-around in a periodic simulation box. A restoring force of magnitude K (R - R0) Mi / M is applied to each atom in the group where {K} is the spring constant, Mi is the mass of the atom, and M is the total mass of all atoms in the group. Note that {K} thus represents the spring constant for the total force on the group of atoms, not for a spring applied to each atom. The {couple} style links two groups of atoms together. The first group is the fix group; the second is specified by group-ID2. The groups are coupled together by a spring that is at equilibrium when the two groups are displaced by a vector {x,y,z} with respect to each other and at a distance R0 from that displacement. Note that {x,y,z} is the equilibrium displacement of group-ID2 relative to the fix group. Thus (1,1,0) is a different spring than (-1,-1,0). When the relative positions and distance between the two groups are not in equilibrium, the same spring force described above is applied to atoms in each of the two groups. For both the {tether} and {couple} styles, any of the x,y,z values can be specified as NULL which means do not include that dimension in the distance calculation or force application. The first example above pulls the ligand towards the point (0,0,0). The second example holds the ligand near the surface of a sphere of radius 5 around the point (0,0,0). The third example holds the ligand a distance 3 away from the z=2 plane (on either side). The fourth example holds 2 bilayers a distance 10 apart in z. For the last two examples, imagine a pore (a slab of atoms with a cylindrical hole cut out) oriented with the pore axis along z, and an ion moving within the pore. The fifth example holds the ion a distance of -20 below the z = 0 center plane of the pore (umbrella sampling). The last example holds the ion a distance 5 away from the pore axis (assuming the center-of-mass of the pore in x,y is the pore axis). NOTE: The center of mass of a group of atoms is calculated in "unwrapped" coordinates using atom image flags, which means that the group can straddle a periodic boundary. See the "dump"_dump.html doc page for a discussion of unwrapped coordinates. It also means that a spring connecting two groups or a group and the tether point can cross -a periodic boundary and its length be calculated correctly. +a periodic boundary and its length be calculated correctly. [Restart, fix_modify, output, run start/stop, minimize 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 add the energy stored in the spring to 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 to set at which level of the "r-RESPA"_run_style.html integrator the fix is adding its forces. Default is the outermost level. This fix computes a global scalar which can be accessed by various "output commands"_Section_howto.html#howto_15. The scalar is the spring energy = 0.5 * K * r^2. This fix also computes global 4-vector which can be accessed by various "output commands"_Section_howto.html#howto_15. The first 3 quantities in the vector are xyz components of the total force added to the group of atoms by the spring. In the case of the {couple} style, it is the force on the fix group (group-ID) or the negative of the force on the 2nd group (group-ID2). The 4th quantity in the vector is the magnitude of the force added by the spring, as a positive value if (r-R0) > 0 and a negative value if (r-R0) < 0. This sign convention can be useful when using the spring force to compute a potential of mean force (PMF). 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. The forces due to this fix are imposed during an energy minimization, invoked by the "minimize"_minimize.html command. NOTE: If you want the spring energy to be included in the total potential energy of the system (the quantity being minimized), you MUST enable the "fix_modify"_fix_modify.html {energy} option for this fix. [Restrictions:] none [Related commands:] "fix drag"_fix_drag.html, "fix spring/self"_fix_spring_self.html, "fix spring/rg"_fix_spring_rg.html, "fix smd"_fix_smd.html [Default:] none diff --git a/doc/src/fix_ti_spring.txt b/doc/src/fix_ti_spring.txt index 40e595e21..afb1dcf8f 100644 --- a/doc/src/fix_ti_spring.txt +++ b/doc/src/fix_ti_spring.txt @@ -1,160 +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 fix ti/spring command :h3 [Syntax:] fix ID group-ID ti/spring k t_s t_eq keyword value ... :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l ti/spring = style name of this fix command :l k = spring constant (force/distance units) :l t_eq = number of steps for the equilibration procedure :l t_s = number of steps for the switching procedure :l zero or more keyword/value pairs may be appended to args :l keyword = {function} :l {function} value = function-ID function-ID = ID of the switching function (1 or 2) :pre :ule [Example:] fix 1 all ti/spring 50.0 2000 1000 function 2 :pre [Description:] This fix allows you to compute the free energy of crystalline solids by performing a nonequilibrium thermodynamic integration between the solid of interest and an Einstein crystal. A detailed explanation of how to use this command and choose its parameters for optimal performance and accuracy is given in the paper by "Freitas"_#Freitas. The paper also presents a short summary of the theory of nonequilibrium thermodynamic integrations. The thermodynamic integration procedure is performed by rescaling the force on each atom. Given an atomic configuration the force (F) on each atom is given by :c,image(Eqs/fix_ti_spring_force.jpg) where F_solid is the force that acts on an atom due to an interatomic potential ({e.g.} EAM potential), F_harm is the force due to the Einstein crystal harmonic spring, and lambda is the coupling parameter of the thermodynamic integration. An Einstein crystal is a solid where each atom is attached to its equilibrium position by a harmonic spring with spring constant {k}. With this fix a spring force is applied independently to each atom in the group defined by the fix to tether it to its initial position. The initial position of each atom is its position at the time the fix command was issued. The fix acts as follows: during the first {t_eq} steps after the fix is defined the value of lambda is zero. This is the period to equilibrate the system in the lambda = 0 state. After this the value of lambda changes dynamically during the simulation from 0 to 1 according to the function defined using the keyword {function} (described below), this switching from lambda from 0 to 1 is done in {t_s} steps. Then comes the second equilibration period of {t_eq} to equilibrate the system in the lambda = 1 state. After that, the switching back to the lambda = 0 state is made using {t_s} timesteps and following the same switching function. After this period the value of lambda is kept equal to zero and the fix has no other effect on the dynamics of the system. The processes described above is known as nonequilibrium thermodynamic integration and is has been shown ("Freitas"_#Freitas) to present a much superior efficiency when compared to standard equilibrium methods. The reason why the switching it is made in both directions (potential to Einstein crystal and back) is to eliminate the dissipated heat due to the nonequilibrium process. Further details about nonequilibrium thermodynamic integration and its implementation in LAMMPS is available in "Freitas"_#Freitas. The {function} keyword allows the use of two different lambda paths. Option {1} results in a constant rate of change of lambda with time: :c,image(Eqs/fix_ti_spring_function_1.jpg) where tau is the scaled time variable {t/t_s}. The option {2} performs the lambda switching at a rate defined by the following switching function :c,image(Eqs/fix_ti_spring_function_2.jpg) This function has zero slope as lambda approaches its extreme values (0 and 1), according to "de Koning"_#deKoning96 this results in smaller fluctuations on the integral to be computed on the thermodynamic integration. The use of option {2} is recommended since it results in better accuracy and less dissipation without any increase in computational resources cost. NOTE: As described in "Freitas"_#Freitas, it is important to keep the center-of-mass fixed during the thermodynamic integration. A nonzero total velocity will result in divergences during the integration due to the fact that the atoms are 'attached' to their equilibrium positions by the Einstein crystal. Check the option {zero} of "fix langevin"_fix_langevin.html and "velocity"_velocity.html. The use of the Nose-Hoover thermostat ("fix nvt"_fix_nh.html) is {NOT} recommended due to its well documented issues with the canonical sampling of harmonic degrees of freedom (notice that the {chain} option will {NOT} solve this problem). The Langevin thermostat ("fix langevin"_fix_langevin.html) correctly thermostats the system and we advise its usage with ti/spring command. [Restart, fix_modify, output, run start/stop, minimize info:] This fix writes the original coordinates of tethered atoms to "binary restart files"_restart.html, so that the spring effect will be the same in a restarted simulation. 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 "fix modify"_fix_modify.html {energy} option is supported by this fix to add the energy stored in the per-atom springs to the system's potential energy as part of "thermodynamic output"_thermo_style.html. This fix computes a global scalar and a global vector quantities which can be accessed by various "output commands"_Section_howto.html#howto_15. The scalar is an energy which is the sum of the spring energy for each atom, where the per-atom energy is 0.5 * k * r^2. The vector has 2 positions, the first one is the coupling parameter lambda and the second one is the time derivative of lambda. 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. The forces due to this fix are imposed during an energy minimization, invoked by the "minimize"_minimize.html command. NOTE: If you want the per-atom spring energy to be included in the total potential energy of the system (the quantity being minimized), you MUST enable the "fix modify"_fix_modify.html {energy} option for this fix. [Related commands:] "fix spring"_fix_spring.html, "fix adapt"_fix_adapt.html -[Restrictions:] none +[Restrictions:] + +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. [Default:] The keyword default is function = 1. :line :link(Freitas) [(Freitas)] Freitas, Asta, and de Koning, Computational Materials Science, 112, 333 (2016). :link(deKoning96) [(de Koning)] de Koning and Antonelli, Phys Rev E, 53, 465 (1996). diff --git a/doc/src/neb.txt b/doc/src/neb.txt index a4afc2fe6..d2e8be3f0 100644 --- a/doc/src/neb.txt +++ b/doc/src/neb.txt @@ -1,427 +1,427 @@ "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 neb command :h3 [Syntax:] neb etol ftol N1 N2 Nevery file-style arg keyword :pre etol = stopping tolerance for energy (energy units) :ulb,l ftol = stopping tolerance for force (force units) :l N1 = max # of iterations (timesteps) to run initial NEB :l N2 = max # of iterations (timesteps) to run barrier-climbing NEB :l Nevery = print replica energies and reaction coordinates every this many timesteps :l file-style = {final} or {each} or {none} :l {final} arg = filename filename = file with initial coords for final replica coords for intermediate replicas are linearly interpolated between first and last replica {each} arg = filename filename = unique filename for each replica (except first) with its initial coords {none} arg = no argument all replicas assumed to already have their initial coords :pre keyword = {verbose} :ule [Examples:] neb 0.1 0.0 1000 500 50 final coords.final neb 0.0 0.001 1000 500 50 each coords.initial.$i neb 0.0 0.001 1000 500 50 none verbose :pre [Description:] Perform a nudged elastic band (NEB) calculation using multiple replicas of a system. Two or more replicas must be used; the first and last are the end points of the transition path. NEB is a method for finding both the atomic configurations and height of the energy barrier associated with a transition state, e.g. for an atom to perform a diffusive hop from one energy basin to another in a coordinated fashion with its neighbors. The implementation in LAMMPS follows the discussion in these 4 papers: "(HenkelmanA)"_#HenkelmanA, "(HenkelmanB)"_#HenkelmanB, "(Nakano)"_#Nakano3 and "(Maras)"_#Maras2. Each replica runs on a partition of one or more processors. Processor partitions are defined at run-time using the -partition command-line switch; see "Section 2.7"_Section_start.html#start_7 of the manual. Note that if you have MPI installed, you can run a multi-replica simulation with more replicas (partitions) than you have physical processors, e.g you can run a 10-replica simulation on just one or two processors. You will simply not get the performance speed-up you would see with one or more physical processors per replica. See "Section 6.5"_Section_howto.html#howto_5 of the manual for further discussion. NOTE: As explained below, a NEB calculation perfoms a damped dynamics minimization across all the replicas. The minimizer uses whatever timestep you have defined in your input script, via the "timestep"_timestep.html command. Often NEB will converge more quickly if you use a timestep about 10x larger than you would normally use for dynamics simulations. When a NEB calculation is performed, it is assumed that each replica is running the same system, though LAMMPS does not check for this. I.e. the simulation domain, the number of atoms, the interaction potentials, and the starting configuration when the neb command is issued should be the same for every replica. In a NEB calculation each replica is connected to other replicas by inter-replica nudging forces. These forces are imposed by the "fix neb"_fix_neb.html command, which must be used in conjunction with the neb command. The group used to define the fix neb command defines the NEB atoms which are the only ones that inter-replica springs are applied to. If the group does not include all atoms, then non-NEB atoms have no inter-replica springs and the forces they feel and their motion is computed in the usual way due only to other atoms within their replica. Conceptually, the non-NEB atoms provide a background force field for the NEB atoms. They can be allowed to move during the NEB minimization procedure (which will typically induce different coordinates for non-NEB atoms in different replicas), or held fixed using other LAMMPS commands such as "fix setforce"_fix_setforce.html. Note that the "partition"_partition.html command can be used to invoke a command on a subset of the replicas, e.g. if you wish to hold NEB or non-NEB atoms fixed in only the end-point replicas. The initial atomic configuration for each of the replicas can be specified in different manners via the {file-style} setting, as discussed below. Only atoms whose initial coordinates should differ from the current configuration need be specified. Conceptually, the initial and final configurations for the first replica should be states on either side of an energy barrier. As explained below, the initial configurations of intermediate replicas can be atomic coordinates interpolated in a linear fashion between the first and last replicas. This is often adequate for simple transitions. For more complex transitions, it may lead to slow convergence or even bad results if the minimum energy path (MEP, see below) of states over the barrier cannot be correctly converged to from such an initial path. In this case, you will want to generate initial states for the intermediate replicas that are geometrically closer to the MEP and read them in. :line For a {file-style} setting of {final}, a filename is specified which contains atomic coordinates for zero or more atoms, in the format described below. For each atom that appears in the file, the new coordinates are assigned to that atom in the final replica. Each intermediate replica also assigns a new position to that atom in an interpolated manner. This is done by using the current position of the atom as the starting point and the read-in position as the final point. The distance between them is calculated, and the new position is assigned to be a fraction of the distance. E.g. if there are 10 replicas, the 2nd replica will assign a position that is 10% of the distance along a line between the starting and final point, and the 9th replica will assign a position that is 90% of the distance along the line. Note that for this procedure to produce consistent coordinates across all the replicas, the current coordinates need to be the same in all replicas. LAMMPS does not check for this, but invalid initial configurations will likely result if it is not the case. NOTE: The "distance" between the starting and final point is calculated in a minimum-image sense for a periodic simulation box. This means that if the two positions are on opposite sides of a box (periodic in that dimension), the distance between them will be small, because the periodic image of one of the atoms is close to the other. Similarly, even if the assigned position resulting from the interpolation is outside the periodic box, the atom will be wrapped back into the box when the NEB calculation begins. For a {file-style} setting of {each}, a filename is specified which is assumed to be unique to each replica. This can be done by using a variable in the filename, e.g. variable i equal part neb 0.0 0.001 1000 500 50 each coords.initial.$i :pre which in this case will substitute the partition ID (0 to N-1) for the variable I, which is also effectively the replica ID. See the "variable"_variable.html command for other options, such as using world-, universe-, or uloop-style variables. Each replica (except the first replica) will read its file, formatted as described below, and for any atom that appears in the file, assign the specified coordinates to its atom. The various files do not need to contain the same set of atoms. For a {file-style} setting of {none}, no filename is specified. Each replica is assumed to already be in its initial configuration at the time the neb command is issued. This allows each replica to define its own configuration by reading a replica-specific data or restart or dump file, via the "read_data"_read_data.html, "read_restart"_read_restart.html, or "read_dump"_read_dump.html commands. The replica-specific names of these files can be specified as in the discussion above for the {each} file-style. Also see the section below for how a NEB calculation can produce restart files, so that a long calculation can be restarted if needed. NOTE: None of the {file-style} settings change the initial configuration of any atom in the first replica. The first replica must thus be in the correct initial configuration at the time the neb command is issued. :line A NEB calculation proceeds in two stages, each of which is a minimization procedure, performed via damped dynamics. To enable this, you must first define a damped dynamics "min_style"_min_style.html, such as {quickmin} or {fire}. The {cg}, {sd}, and {hftn} styles cannot be used, since they perform iterative line searches in their inner loop, which cannot be easily synchronized across multiple replicas. The minimizer tolerances for energy and force are set by {etol} and {ftol}, the same as for the "minimize"_minimize.html command. A non-zero {etol} means that the NEB calculation will terminate if the energy criterion is met by every replica. The energies being compared to {etol} do not include any contribution from the inter-replica nudging forces, since these are non-conservative. A non-zero {ftol} means that the NEB calculation will terminate if the force criterion is met by every replica. The forces being compared to {ftol} include the inter-replica nudging forces. The maximum number of iterations in each stage is set by {N1} and {N2}. These are effectively timestep counts since each iteration of damped dynamics is like a single timestep in a dynamics "run"_run.html. During both stages, the potential energy of each replica and its normalized distance along the reaction path (reaction coordinate RD) will be printed to the screen and log file every {Nevery} timesteps. The RD is 0 and 1 for the first and last replica. For intermediate replicas, it is the cumulative distance (normalized by the total cumulative distance) between adjacent replicas, where "distance" is defined as the length of the 3N-vector of differences in atomic coordinates, where N is the number of NEB atoms involved in the transition. These outputs allow you to monitor NEB's progress in finding a good energy barrier. {N1} and {N2} must both be multiples of {Nevery}. In the first stage of NEB, the set of replicas should converge toward a minimum energy path (MEP) of conformational states that transition over a barrier. The MEP for a transition is defined as a sequence of 3N-dimensional states, each of which has a potential energy gradient parallel to the MEP itself. The configuration of highest energy along a MEP corresponds to a saddle point. The replica states will also be roughly equally spaced along the MEP due to the inter-replica nugding force added by the "fix neb"_fix_neb.html command. In the second stage of NEB, the replica with the highest energy is selected and the inter-replica forces on it are converted to a force that drives its atom coordinates to the top or saddle point of the barrier, via the barrier-climbing calculation described in "(HenkelmanB)"_#HenkelmanB. As before, the other replicas rearrange themselves along the MEP so as to be roughly equally spaced. When both stages are complete, if the NEB calculation was successful, the configurations of the replicas should be along (close to) the MEP and the replica with the highest energy should be an atomic configuration at (close to) the saddle point of the transition. The potential energies for the set of replicas represents the energy profile of the transition along the MEP. :line A few other settings in your input script are required or advised to perform a NEB calculation. See the NOTE about the choice of timestep at the beginning of this doc page. An atom map must be defined which it is not by default for "atom_style atomic"_atom_style.html problems. The "atom_modify map"_atom_modify.html command can be used to do this. The minimizers in LAMMPS operate on all atoms in your system, even non-NEB atoms, as defined above. To prevent non-NEB atoms from moving during the minimization, you should use the "fix setforce"_fix_setforce.html command to set the force on each of those atoms to 0.0. This is not required, and may not even be desired in some cases, but if those atoms move too far (e.g. because the initial state of your system was not well-minimized), it can cause problems for the NEB procedure. The damped dynamics "minimizers"_min_style.html, such as {quickmin} and {fire}), adjust the position and velocity of the atoms via an Euler integration step. Thus you must define an appropriate "timestep"_timestep.html to use with NEB. As mentioned above, NEB will often converge more quickly if you use a timestep about 10x larger than you would normally use for dynamics simulations. :line Each file read by the neb command containing atomic coordinates used to initialize one or more replicas must be formatted as follows. The file can be ASCII text or a gzipped text file (detected by a .gz suffix). The file can contain initial blank lines or comment lines starting with "#" which are ignored. The first non-blank, non-comment line should list N = the number of lines to follow. The N successive lines contain the following information: ID1 x1 y1 z1 ID2 x2 y2 z2 ... IDN xN yN zN :pre The fields are the atom ID, followed by the x,y,z coordinates. The lines can be listed in any order. Additional trailing information on the line is OK, such as a comment. Note that for a typical NEB calculation you do not need to specify initial coordinates for very many atoms to produce differing starting and final replicas whose intermediate replicas will converge to the energy barrier. Typically only new coordinates for atoms geometrically near the barrier need be specified. Also note there is no requirement that the atoms in the file correspond to the NEB atoms in the group defined by the "fix neb"_fix_neb.html command. Not every NEB atom need be in the file, and non-NEB atoms can be listed in the file. :line Four kinds of output can be generated during a NEB calculation: energy barrier statistics, thermodynamic output by each replica, dump files, and restart files. When running with multiple partitions (each of which is a replica in this case), the print-out to the screen and master log.lammps file contains a line of output, printed once every {Nevery} timesteps. It contains the timestep, the maximum force per replica, the maximum force per atom (in any replica), potential gradients in the initial, final, and climbing replicas, the forward and backward energy barriers, the total reaction coordinate (RDT), and the normalized reaction coordinate and potential energy of each replica. The "maximum force per replica" is the two-norm of the 3N-length force vector for the atoms in each replica, maximized across replicas, which is what the {ftol} setting is checking against. In this case, N is all the atoms in each replica. The "maximum force per atom" is the maximum force component of any atom in any replica. The potential gradients are the two-norm of the 3N-length force vector solely due to the interaction potential i.e. without adding in inter-replica forces. The "reaction coordinate" (RD) for each replica is the two-norm of the 3N-length vector of distances between its atoms and the preceding replica's atoms, added to the RD of the preceding replica. The RD of the first replica RD1 = 0.0; the RD of the final replica RDN = RDT, the total reaction coordinate. The normalized RDs are divided by RDT, so that they form a monotonically increasing sequence from zero to one. When computing RD, N only includes the atoms being operated on by the fix neb command. The forward (reverse) energy barrier is the potential energy of the highest replica minus the energy of the first (last) replica. Supplementary informations for all replicas can be printed out to the screen and master log.lammps file by adding the verbose keyword. These informations include the following. The "path angle" (pathangle) for the replica i which is the angle between the 3N-length vectors (Ri-1 - Ri) and (Ri+1 - Ri) (where Ri is the atomic coordinates of replica i). A "path angle" of 180 indicates that replicas i-1, i and i+1 are aligned. "angletangrad" is the angle between the 3N-length tangent vector and the 3N-length force vector at image i. The tangent vector is calculated as in "(HenkelmanA)"_#HenkelmanA for all intermediate replicas and at R2 - R1 and RM - RM-1 for the first and last replica, respectively. "anglegrad" is the angle between the 3N-length energy gradient vector of replica i and that of replica i+1. It is not defined for the final replica and reads nan. gradV is the norm of the energy gradient of image i. ReplicaForce is the two-norm of the 3N-length force vector (including nudging forces) for replica i. MaxAtomForce is the maximum force component of any atom in replica i. When a NEB calculation does not converge properly, these suplementary informations can help understanding what is going wrong. For instance when the path angle becomes accute the definition of tangent used in the NEB calculation is questionable and the NEB cannot may diverge "(Maras)"_#Maras2. - + When running on multiple partitions, LAMMPS produces additional log files for each partition, e.g. log.lammps.0, log.lammps.1, etc. For a NEB calculation, these contain the thermodynamic output for each replica. If "dump"_dump.html commands in the input script define a filename that includes a {universe} or {uloop} style "variable"_variable.html, then one dump file (per dump command) will be created for each replica. At the end of the NEB calculation, the final snapshot in each file will contain the sequence of snapshots that transition the system over the energy barrier. Earlier snapshots will show the convergence of the replicas to the MEP. Likewise, "restart"_restart.html filenames can be specified with a {universe} or {uloop} style "variable"_variable.html, to generate restart files for each replica. These may be useful if the NEB calculation fails to converge properly to the MEP, and you wish to restart the calculation from an intermediate point with altered parameters. There are 2 Python scripts provided in the tools/python directory, neb_combine.py and neb_final.py, which are useful in analyzing output from a NEB calculation. Assume a NEB simulation with M replicas, and the NEB atoms labeled with a specific atom type. The neb_combine.py script extracts atom coords for the NEB atoms from all M dump files and creates a single dump file where each snapshot contains the NEB atoms from all the replicas and one copy of non-NEB atoms from the first replica (presumed to be identical in other replicas). This can be visualized/animated to see how the NEB atoms relax as the NEB calculation proceeds. The neb_final.py script extracts the final snapshot from each of the M dump files to create a single dump file with M snapshots. This can be visualized to watch the system make its transition over the energy barrier. To illustrate, here are images from the final snapshot produced by the neb_combine.py script run on the dump files produced by the two example input scripts in examples/neb. Click on them to see a larger image. :image(JPG/hop1_small.jpg,JPG/hop1.jpg) :image(JPG/hop2_small.jpg,JPG/hop2.jpg) :line [Restrictions:] This command 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. :line [Related commands:] "prd"_prd.html, "temper"_temper.html, "fix langevin"_fix_langevin.html, "fix viscous"_fix_viscous.html [Default:] none :line :link(HenkelmanA) [(HenkelmanA)] Henkelman and Jonsson, J Chem Phys, 113, 9978-9985 (2000). :link(HenkelmanB) [(HenkelmanB)] Henkelman, Uberuaga, Jonsson, J Chem Phys, 113, 9901-9904 (2000). :link(Nakano3) [(Nakano)] Nakano, Comp Phys Comm, 178, 280-289 (2008). :link(Maras2) [(Maras)] Maras, Trushin, Stukowski, Ala-Nissila, Jonsson, Comp Phys Comm, 205, 13-21 (2016) diff --git a/doc/src/pair_agni.txt b/doc/src/pair_agni.txt index 27fb6c10f..06dcccb9d 100644 --- a/doc/src/pair_agni.txt +++ b/doc/src/pair_agni.txt @@ -1,128 +1,128 @@ "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 agni command :h3 pair_style agni/omp command :h3 [Syntax:] pair_style agni :pre [Examples:] pair_style agni pair_coeff * * Al.agni Al [Description:] Style {agni} style computes the manybody vectorial force components for an atom as :c,image(Eqs/pair_agni.jpg) {u} labels the individual components, i.e. x, y or z, and {V} is the corresponding atomic fingerprint. {d} is the Euclidean distance between any two atomic fingerprints. A total of N_t reference atomic environments are considered to construct the force field file. {alpha_t} and {l} are the weight coefficients and length scale parameter of the non-linear regression model. The method implements the recently proposed machine learning access to atomic forces as discussed extensively in the following publications - "(Botu1)"_#Botu2015adaptive and "(Botu2)"_#Botu2015learning. The premise of the method is to map the atomic environment numerically into a fingerprint, and use machine learning methods to create a mapping to the vectorial atomic forces. Only a single pair_coeff command is used with the {agni} style which specifies an AGNI potential file containing the parameters of the -force field for the needed elements. These are mapped to LAMMPS atom -types by specifying N additional arguments after the filename in the +force field for the 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 element names = mapping of AGNI elements to atom types :ul See the "pair_coeff"_pair_coeff.html doc page for alternate ways to specify the path for the force field file. An AGNI force field is fully specified by the filename which contains the parameters of the force field, i.e., the reference training environments -used to construct the machine learning force field. Example force field -and input files are provided in the examples/USER/misc/agni directory. +used to construct the machine learning force field. Example force field +and input files are provided in the examples/USER/misc/agni directory. :line -Styles with {omp} suffix is functionally the same as the corresponding -style without the suffix. They have been optimized to run faster, depending +Styles with {omp} suffix is 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 style takes the same arguments and should produce the same results, except for round-off and precision issues. The accelerated style is part of the USER-OMP. 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 style 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]: 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:] Currently, only elemental systems are implemented. Also, the method only provides access to the forces and not energies or stresses. However, one can access the energy via thermodynamic integration of the forces as discussed in "(Botu3)"_#Botu2016construct. This pair style 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. The AGNI force field files provided with LAMMPS (see the potentials directory) are parameterized for metal "units"_units.html. You can use the AGNI potential with any LAMMPS units, but you would need to create your own AGNI potential file with coefficients listed in the appropriate units if your simulation doesn't use "metal" units. [Related commands:] "pair_coeff"_pair_coeff.html [Default:] none :line :link(Botu2015adaptive) [(Botu1)] V. Botu and R. Ramprasad, Int. J. Quant. Chem., 115(16), 1074 (2015). :link(Botu2015learning) [(Botu2)] V. Botu and R. Ramprasad, Phys. Rev. B, 92(9), 094306 (2015). :link(Botu2016construct) [(Botu3)] V. Botu, R. Batra, J. Chapman and R. Ramprasad, https://arxiv.org/abs/1610.02098 (2016). diff --git a/doc/src/pair_buck.txt b/doc/src/pair_buck.txt index 49161404c..e705e735f 100644 --- a/doc/src/pair_buck.txt +++ b/doc/src/pair_buck.txt @@ -1,201 +1,201 @@ "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 buck command :h3 pair_style buck/gpu command :h3 pair_style buck/intel command :h3 pair_style buck/kk command :h3 pair_style buck/omp command :h3 pair_style buck/coul/cut command :h3 pair_style buck/coul/cut/gpu command :h3 pair_style buck/coul/cut/intel command :h3 pair_style buck/coul/cut/kk command :h3 pair_style buck/coul/cut/omp command :h3 pair_style buck/coul/long command :h3 pair_style buck/coul/long/cs command :h3 pair_style buck/coul/long/gpu command :h3 pair_style buck/coul/long/intel command :h3 pair_style buck/coul/long/kk command :h3 pair_style buck/coul/long/omp command :h3 pair_style buck/coul/msm command :h3 pair_style buck/coul/msm/omp command :h3 [Syntax:] pair_style style args :pre style = {buck} or {buck/coul/cut} or {buck/coul/long} or {buck/coul/long/cs} or {buck/coul/msm} args = list of arguments for a particular style :ul {buck} args = cutoff cutoff = global cutoff for Buckingham interactions (distance units) {buck/coul/cut} args = cutoff (cutoff2) cutoff = global cutoff for Buckingham (and Coulombic if only 1 arg) (distance units) cutoff2 = global cutoff for Coulombic (optional) (distance units) {buck/coul/long} or {buck/coul/long/cs} args = cutoff (cutoff2) cutoff = global cutoff for Buckingham (and Coulombic if only 1 arg) (distance units) cutoff2 = global cutoff for Coulombic (optional) (distance units) {buck/coul/msm} args = cutoff (cutoff2) cutoff = global cutoff for Buckingham (and Coulombic if only 1 arg) (distance units) cutoff2 = global cutoff for Coulombic (optional) (distance units) :pre [Examples:] pair_style buck 2.5 pair_coeff * * 100.0 1.5 200.0 pair_coeff * * 100.0 1.5 200.0 3.0 :pre pair_style buck/coul/cut 10.0 pair_style buck/coul/cut 10.0 8.0 pair_coeff * * 100.0 1.5 200.0 pair_coeff 1 1 100.0 1.5 200.0 9.0 pair_coeff 1 1 100.0 1.5 200.0 9.0 8.0 :pre pair_style buck/coul/long 10.0 pair_style buck/coul/long/cs 10.0 pair_style buck/coul/long 10.0 8.0 pair_style buck/coul/long/cs 10.0 8.0 pair_coeff * * 100.0 1.5 200.0 pair_coeff 1 1 100.0 1.5 200.0 9.0 :pre pair_style buck/coul/msm 10.0 pair_style buck/coul/msm 10.0 8.0 pair_coeff * * 100.0 1.5 200.0 pair_coeff 1 1 100.0 1.5 200.0 9.0 :pre [Description:] The {buck} style computes a Buckingham potential (exp/6 instead of Lennard-Jones 12/6) given by :c,image(Eqs/pair_buck.jpg) where rho is an ionic-pair dependent length parameter, and Rc is the -cutoff on both terms. +cutoff on both terms. The styles with {coul/cut} or {coul/long} or {coul/msm} add a Coulombic term as described for the "lj/cut"_pair_lj.html pair styles. For {buck/coul/long} and {buc/coul/msm}, an additional damping factor is applied to the Coulombic term so it can be used in conjunction with the "kspace_style"_kspace_style.html command and its {ewald} or {pppm} or {msm} option. The Coulombic cutoff specified for this style means that pairwise interactions within this distance are computed directly; interactions outside that distance are computed in reciprocal space. If one cutoff is specified for the {born/coul/cut} and {born/coul/long} and {born/coul/msm} styles, it is used for both the A,C and Coulombic terms. If two cutoffs are specified, the first is used as the cutoff for the A,C terms, and the second is the cutoff for the Coulombic term. Style {buck/coul/long/cs} is identical to {buck/coul/long} except that a term is added for the "core/shell model"_Section_howto.html#howto_25 to allow charges on core and shell particles to be separated by r = 0.0. Note that these potentials are related to the "Born-Mayer-Huggins potential"_pair_born.html. NOTE: For all these pair styles, the terms with A and C are always cutoff. The additional Coulombic term can be cutoff or long-range (no cutoff) depending on whether the style name includes coul/cut or coul/long or coul/msm. If you wish the C/r^6 term to be long-range (no cutoff), then see the "pair_style buck/long/coul/long"_pair_buck_long.html command. The following coefficients must be defined for each pair of atoms types via the "pair_coeff"_pair_coeff.html command as in the examples above, or in the data file or restart files read by the "read_data"_read_data.html or "read_restart"_read_restart.html commands: A (energy units) rho (distance units) C (energy-distance^6 units) cutoff (distance units) cutoff2 (distance units) :ul The second coefficient, rho, must be greater than zero. The coefficients A, rho, and C can be written as analytical expressions of epsilon and sigma, in analogy to the Lennard-Jones potential "(Khrapak)"_#Khrapak. The latter 2 coefficients are optional. If not specified, the global A,C and Coulombic cutoffs are used. If only one cutoff is specified, it is used as the cutoff for both A,C and Coulombic interactions for this type pair. If both coefficients are specified, they are used as the A,C and Coulombic cutoffs for this type pair. You cannot specify 2 cutoffs for style {buck}, since it has no Coulombic terms. For {buck/coul/long} only the LJ cutoff can be specified since a Coulombic cutoff cannot be specified for an individual I,J type pair. All type pairs use the same global Coulombic cutoff specified in the pair_style command. :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 [Mixing, shift, table, tail correction, restart, rRESPA info]: These pair styles do not support mixing. Thus, coefficients for all I,J pairs must be specified explicitly. These styles support the "pair_modify"_pair_modify.html shift option for the energy of the exp() and 1/r^6 portion of the pair interaction. The {buck/coul/long} pair style supports the "pair_modify"_pair_modify.html table option to tabulate the short-range portion of the long-range Coulombic interaction. These styles support the pair_modify tail option for adding long-range tail corrections to energy and pressure for the A,C terms in the pair interaction. These styles write their information to "binary restart files"_restart.html, so pair_style and pair_coeff commands do not need to be specified in an input script that reads a restart file. These styles can only be used via the {pair} keyword of the "run_style respa"_run_style.html command. They do not support the {inner}, {middle}, {outer} keywords. [Restrictions:] The {buck/coul/long} style is part of the KSPACE package. The {buck/coul/long/cs} style is part of the CORESHELL 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. [Related commands:] "pair_coeff"_pair_coeff.html, "pair_style born"_pair_born.html [Default:] none :link(Khrapak) [(Khrapak)] Khrapak, Chaudhuri, and Morfill, J Chem Phys, 134, 054120 (2011). diff --git a/doc/src/pair_exp6_rx.txt b/doc/src/pair_exp6_rx.txt index 47045a593..cbc17d357 100644 --- a/doc/src/pair_exp6_rx.txt +++ b/doc/src/pair_exp6_rx.txt @@ -1,160 +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 pair_style exp6/rx command :h3 [Syntax:] pair_style exp6/rx cutoff ... :pre cutoff = global cutoff for DPD interactions (distance units) weighting = fractional or molecular (optional) :ul [Examples:] pair_style exp6/rx 10.0 pair_style exp6/rx 10.0 fractional pair_style exp6/rx 10.0 molecular pair_coeff * * exp6.params h2o h2o exponent 1.0 1.0 10.0 pair_coeff * * exp6.params h2o 1fluid exponent 1.0 1.0 10.0 pair_coeff * * exp6.params 1fluid 1fluid exponent 1.0 1.0 10.0 pair_coeff * * exp6.params 1fluid 1fluid none 10.0 pair_coeff * * exp6.params 1fluid 1fluid polynomial filename 10.0 :pre [Description:] Style {exp6/rx} is used in reaction DPD simulations, where the coarse-grained (CG) particles are composed of {m} species whose reaction rate kinetics are determined from a set of {n} reaction rate equations through the "fix rx"_fix_rx.html command. The species of one CG particle can interact with a species in a neighboring CG particle through a site-site interaction potential model. The {exp6/rx} style computes an exponential-6 potential given by :c,image(Eqs/pair_exp6_rx.jpg) where the {epsilon} parameter determines the depth of the potential minimum located at {Rm}, and {alpha} determines the softness of the repulsion. The coefficients must be defined for each species in a given particle type via the "pair_coeff"_pair_coeff.html command as in the examples above, where the first argument is the filename that includes the exponential-6 parameters for each species. The file includes the species tag followed by the {alpha}, {epsilon} and {Rm} parameters. The format of the file is described below. The second and third arguments specify the site-site interaction potential between two species contained within two different particles. The species tags must either correspond to the species defined in the reaction kinetics files specified with the "fix rx"_fix_rx.html command or they must correspond to the tag "1fluid", signifying interaction with a product species mixture determined through a one-fluid approximation. The interaction potential is -weighted by the geometric average of either the mole fraction concentrations -or the number of molecules associated with the interacting coarse-grained -particles (see the {fractional} or {molecular} weighting pair style options). +weighted by the geometric average of either the mole fraction concentrations +or the number of molecules associated with the interacting coarse-grained +particles (see the {fractional} or {molecular} weighting pair style options). The coarse-grained potential is stored before and after the reaction kinetics solver is applied, where the difference is defined to be the internal chemical energy (uChem). -The fourth argument specifies the type of scaling that will be used +The fourth argument specifies the type of scaling that will be used to scale the EXP-6 parameters as reactions occur. Currently, there are three scaling options: {exponent}, {polynomial} and {none}. -Exponent scaling requires two additional arguments for scaling +Exponent scaling requires two additional arguments for scaling the {Rm} and {epsilon} parameters, respectively. The scaling factor -is computed by phi^exponent, where phi is the number of molecules -represented by the coarse-grain particle and exponent is specified +is computed by phi^exponent, where phi is the number of molecules +represented by the coarse-grain particle and exponent is specified as a pair coefficient argument for {Rm} and {epsilon}, respectively. -The {Rm} and {epsilon} parameters are multiplied by the scaling +The {Rm} and {epsilon} parameters are multiplied by the scaling factor to give the scaled interaction parameters for the CG particle. -Polynomial scaling requires a filename to be specified as a pair +Polynomial scaling requires a filename to be specified as a pair coeff argument. The file contains the coefficients to a fifth order -polynomial for the {alpha}, {epsilon} and {Rm} parameters that depend -upon phi (the number of molecules represented by the CG particle). +polynomial for the {alpha}, {epsilon} and {Rm} parameters that depend +upon phi (the number of molecules represented by the CG particle). The format of a polynomial file is provided below. The {none} option to the scaling does not have any additional pair coeff -arguments. This is equivalent to specifying the {exponent} option with +arguments. This is equivalent to specifying the {exponent} option with {Rm} and {epsilon} exponents of 0.0 and 0.0, respectively. The final argument specifies the interaction cutoff (optional). :line The format of a tabulated file is as follows (without the parenthesized comments): # exponential-6 parameters for various species (one or more comment or blank lines) :pre h2o exp6 11.00 0.02 3.50 (species, exp6, alpha, Rm, epsilon) no2 exp6 13.60 0.01 3.70 ... co2 exp6 13.00 0.03 3.20 :pre The format of the polynomial scaling file as follows (without the parenthesized comments): # POLYNOMIAL FILE (one or more comment or blank lines) :pre # General Functional Form: -# A*phi^5 + B*phi^4 + C*phi^3 + D*phi^2 + E*phi + F +# A*phi^5 + B*phi^4 + C*phi^3 + D*phi^2 + E*phi + F # # Parameter A B C D E F (blank) alpha 0.0000 0.00000 0.00008 0.04955 -0.73804 13.63201 epsilon 0.0000 0.00478 -0.06283 0.24486 -0.33737 2.60097 rm 0.0001 -0.00118 -0.00253 0.05812 -0.00509 1.50106 :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 species and their corresponding parameters. The first argument is the species tag, the second argument is the exp6 tag, the 3rd argument is the {alpha} parameter (energy units), the 4th argument is the {epsilon} parameter (energy-distance^6 units), and the 5th argument is the {Rm} parameter (distance units). If a species tag of "1fluid" is listed as a pair coefficient, a one-fluid approximation is specified where a concentration-dependent combination of the parameters is computed through the following equations: :c,image(Eqs/pair_exp6_rx_oneFluid.jpg) where :c,image(Eqs/pair_exp6_rx_oneFluid2.jpg) and xa and xb are the mole fractions of a and b, respectively, which comprise the gas mixture. :line [Mixing, shift, table, tail correction, restart, rRESPA info]: This pair style does not support mixing. Thus, coefficients for all I,J pairs must be specified explicitly. This style does not support the "pair_modify"_pair_modify.html shift option for the energy of the exp() and 1/r^6 portion of the pair interaction. This style does not support the pair_modify tail option for adding long-range tail corrections to energy and pressure for the A,C terms in the pair interaction. [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. [Related commands:] "pair_coeff"_pair_coeff.html [Default:] fractional weighting diff --git a/doc/src/pair_kolmogorov_crespi_z.txt b/doc/src/pair_kolmogorov_crespi_z.txt index 0879dc34d..c7a6d4194 100644 --- a/doc/src/pair_kolmogorov_crespi_z.txt +++ b/doc/src/pair_kolmogorov_crespi_z.txt @@ -1,72 +1,72 @@ "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 kolmogorov/crespi/z command :h3 [Syntax:] pair_style hybrid/overlay kolmogorov/crespi/z cutoff :pre [Examples:] pair_style hybrid/overlay kolmogorov/crespi/z 20.0 pair_coeff * * none pair_coeff 1 2 kolmogorov/crespi/z CC.KC C C :pre pair_style hybrid/overlay rebo kolmogorov/crespi/z 14.0 pair_coeff * * rebo CH.airebo C C pair_coeff 1 2 kolmogorov/crespi/z CC.KC C C :pre [Description:] -The {kolmogorov/crespi/z} style computes the Kolmogorov-Crespi interaction -potential as described in "(KC05)"_#KC05. An important simplification is made, -which is to take all normals along the z-axis. +The {kolmogorov/crespi/z} style computes the Kolmogorov-Crespi interaction +potential as described in "(KC05)"_#KC05. An important simplification is made, +which is to take all normals along the z-axis. :c,image(Eqs/pair_kolmogorov_crespi_z.jpg) -It is important to have a suffiently large cutoff to ensure smooth forces. -Energies are shifted so that they go continously to zero at the cutoff assuming +It is important to have a suffiently large cutoff to ensure smooth forces. +Energies are shifted so that they go continously to zero at the cutoff assuming that the exponential part of {Vij} (first term) decays sufficiently fast. This shift is achieved by the last term in the equation for {Vij} above. -This potential is intended for interactions between two layers of graphene. -Therefore, to avoid interaction between layers in multi-layered materials, -each layer should have a separate atom type and interactions should only +This potential is intended for interactions between two layers of graphene. +Therefore, to avoid interaction between layers in multi-layered materials, +each layer should have a separate atom type and interactions should only be computed between atom types of neighbouring layers. -The parameter file (e.g. CC.KC), is intended for use with metal -"units"_units.html, with energies in meV. An additional parameter, {S}, -is available to facilitate scaling of energies in accordance with +The parameter file (e.g. CC.KC), is intended for use with metal +"units"_units.html, with energies in meV. An additional parameter, {S}, +is available to facilitate scaling of energies in accordance with "(vanWijk)"_#vanWijk. This potential must be used in combination with hybrid/overlay. Other interactions can be set to zero using pair_style {none}. [Restrictions:] 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. [Related commands:] "pair_coeff"_pair_coeff.html "pair_none"_pair_none.html "pair_style hybrid/overlay"_pair_hybrid.html [Default:] none :line -:link(KC05) +:link(KC05) [(KC05)] A. N. Kolmogorov, V. H. Crespi, Phys. Rev. B 71, 235415 (2005) :link(vanWijk) [(vanWijk)] M. M. van Wijk, A. Schuring, M. I. Katsnelson, and A. Fasolino, Physical Review Letters, 113, 135504 (2014) diff --git a/doc/src/pair_multi_lucy_rx.txt b/doc/src/pair_multi_lucy_rx.txt index bf5d5636f..77ed223e2 100644 --- a/doc/src/pair_multi_lucy_rx.txt +++ b/doc/src/pair_multi_lucy_rx.txt @@ -1,225 +1,225 @@ "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 multi/lucy/rx command :h3 [Syntax:] pair_style multi/lucy/rx style N keyword ... :pre style = {lookup} or {linear} = method of interpolation N = use N values in {lookup}, {linear} tables weighting = fractional or molecular (optional) :ul [Examples:] pair_style multi/lucy/rx linear 1000 pair_style multi/lucy/rx linear 1000 fractional pair_style multi/lucy/rx linear 1000 molecular pair_coeff * * multibody.table ENTRY1 h2o h2o 7.0 pair_coeff * * multibody.table ENTRY1 h2o 1fluid 7.0 :pre [Description:] Style {multi/lucy/rx} is used in reaction DPD simulations, where the coarse-grained (CG) particles are composed of {m} species whose reaction rate kinetics are determined from a set of {n} reaction rate equations through the "fix rx"_fix_rx.html command. The species of one CG particle can interact with a species in a neighboring CG particle through a site-site interaction potential model. Style {multi/lucy/rx} computes the site-site density-dependent force following from the many-body form described in "(Moore)"_#Moore2 and "(Warren)"_#Warren2 as :c,image(Eqs/pair_multi_lucy.jpg) which consists of a density-dependent function, A(rho), and a radial-dependent weight function, omegaDD(rij). The radial-dependent weight function, omegaDD(rij), is taken as the Lucy function: :c,image(Eqs/pair_multi_lucy2.jpg) The density-dependent energy for a given particle is given by: :c,image(Eqs/pair_multi_lucy_energy.jpg) See the supporting information of "(Brennan)"_#Brennan2 or the publication by "(Moore)"_#Moore2 for more details on the functional form. An interpolation table is used to evaluate the density-dependent energy (Integral(A(rho)drho) and force (A(rho)). Note that the pre-factor to the energy is computed after the interpolation, thus the Integral(A(rho)drho will have units of energy / length^4. The interpolation table is created as a pre-computation by fitting cubic splines to the file values and interpolating the density-dependent energy and force at each of {N} densities. During a simulation, the tables are used to interpolate the density-dependent energy and force as needed for each pair of particles separated by a distance {R}. The interpolation is done in one of 2 styles: {lookup} and {linear}. For the {lookup} style, the density is used to find the nearest table entry, which is the density-dependent energy and force. For the {linear} style, the density is used to find the 2 surrounding table values from which the density-dependent energy and force are computed by linear interpolation. The following coefficients must be defined for each pair of atoms types via the "pair_coeff"_pair_coeff.html command as in the examples above. filename keyword species1 species2 cutoff (distance units) :ul The filename specifies a file containing the tabulated density-dependent energy and force. The keyword specifies a section of the file. The cutoff is an optional coefficient. If not specified, the outer cutoff in the table itself (see below) will be used to build an interpolation table that extend to the largest tabulated distance. If specified, only file values up to the cutoff are used to create the interpolation table. The format of this file is described below. The species tags define the site-site interaction potential between two species contained within two different particles. The species tags must either correspond to the species defined in the reaction kinetics files specified with the "fix rx"_fix_rx.html command or they must correspond to the tag "1fluid", signifying interaction with a product species mixture determined through a one-fluid approximation. -The interaction potential is weighted by the geometric average of -either the mole fraction concentrations or the number of molecules -associated with the interacting coarse-grained particles (see the +The interaction potential is weighted by the geometric average of +either the mole fraction concentrations or the number of molecules +associated with the interacting coarse-grained particles (see the {fractional} or {molecular} weighting pair style options). The coarse-grained potential is stored before and after the reaction kinetics solver is applied, where the difference is defined to be the internal chemical energy (uChem). :line The format of a tabulated file is a series of one or more sections, defined as follows (without the parenthesized comments): # Density-dependent function (one or more comment or blank lines) :pre DD-FUNCTION (keyword is first text on line) N 500 R 1.0 10.0 (N, R, RSQ parameters) (blank) 1 1.0 25.5 102.34 (index, density, energy/r^4, force) 2 1.02 23.4 98.5 ... 500 10.0 0.001 0.003 :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. The first line begins with a keyword which identifies the section. The line can contain additional text, but the initial text must match the argument specified in the pair_coeff command. The next line lists (in any order) one or more parameters for the table. Each parameter is a keyword followed by one or more numeric values. The parameter "N" is required and its value is the number of table entries that follow. Note that this may be different than the {N} specified in the "pair_style multi/lucy/rx"_pair_multi_lucy_rx.html command. Let Ntable = {N} in the pair_style command, and Nfile = "N" in the tabulated file. What LAMMPS does is a preliminary interpolation by creating splines using the Nfile tabulated values as nodal points. It uses these to interpolate the density-dependent energy and force at Ntable different points. The resulting tables of length Ntable are then used as described above, when computing the density-dependent energy and force. This means that if you want the interpolation tables of length Ntable to match exactly what is in the tabulated file (with effectively no preliminary interpolation), you should set Ntable = Nfile, and use the "RSQ" parameter. This is because the internal table abscissa is always RSQ (separation distance squared), for efficient lookup. All other parameters are optional. If "R" or "RSQ" does not appear, then the distances in each line of the table are used as-is to perform spline interpolation. In this case, the table values can be spaced in {density} uniformly or however you wish to position table values in regions of large gradients. If used, the parameters "R" or "RSQ" are followed by 2 values {rlo} and {rhi}. If specified, the density associated with each density-dependent energy and force value is computed from these 2 values (at high accuracy), rather than using the (low-accuracy) value listed in each line of the table. The density values in the table file are ignored in this case. For "R", distances uniformly spaced between {rlo} and {rhi} are computed; for "RSQ", squared distances uniformly spaced between {rlo*rlo} and {rhi*rhi} are computed. NOTE: If you use "R" or "RSQ", the tabulated distance values in the file are effectively ignored, and replaced by new values as described in the previous paragraph. If the density value in the table is not very close to the new value (i.e. round-off difference), then you will be assigning density-dependent energy and force values to a different density, which is probably not what you want. LAMMPS will warn if this is occurring. Following a blank line, the next N lines list the tabulated values. On each line, the 1st value is the index from 1 to N, the 2nd value is r (in density units), the 3rd value is the density-dependent function value (in energy units / length^4), and the 4th is the force (in force units). The density values must increase from one line to the next. Note that one file can contain many sections, each with a tabulated potential. LAMMPS reads the file section by section until it finds one that matches the specified keyword. :line [Mixing, shift, table, tail correction, restart, rRESPA info]: This pair style does not support mixing. Thus, coefficients for all I,J pairs must be specified explicitly. The "pair_modify"_pair_modify.html shift, table, and tail options are not relevant for this pair style. This pair style writes the settings for the "pair_style multi/lucy/rx" command to "binary restart files"_restart.html, so a pair_style 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, since it is tabulated in the potential files. Thus, pair_coeff commands do need to be specified in the restart input script. 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 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. [Related commands:] "pair_coeff"_pair_coeff.html [Default:] fractional weighting :line :link(Warren2) [(Warren)] Warren, Phys Rev E, 68, 066702 (2003). :link(Brennan2) [(Brennan)] Brennan, J Chem Phys Lett, 5, 2144-2149 (2014). :link(Moore2) [(Moore)] Moore, J Chem Phys, 144, 104501 (2016). diff --git a/doc/src/pair_oxdna.txt b/doc/src/pair_oxdna.txt index 0a07417fd..d9734f122 100644 --- a/doc/src/pair_oxdna.txt +++ b/doc/src/pair_oxdna.txt @@ -1,92 +1,92 @@ "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 oxdna/excv command :h3 pair_style oxdna/stk command :h3 pair_style oxdna/hbond command :h3 pair_style oxdna/xstk command :h3 pair_style oxdna/coaxstk command :h3 [Syntax:] pair_style style1 :pre pair_coeff * * style2 args :pre style1 = {hybrid/overlay oxdna/excv oxdna/stk oxdna/hbond oxdna/xstk oxdna/coaxstk} :ul style2 = {oxdna/stk} args = list of arguments for these two particular styles :ul {oxdna2/stk} args = T 6.0 0.4 0.9 0.32 0.6 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 2.0 0.65 2.0 0.65 T = temperature (oxDNA units, 0.1 = 300 K) :pre [Examples:] pair_style hybrid/overlay oxdna/excv oxdna/stk oxdna/hbond oxdna/xstk oxdna/coaxstk pair_coeff * * oxdna/excv 2.0 0.7 0.675 2.0 0.515 0.5 2.0 0.33 0.32 pair_coeff * * oxdna/stk 0.1 6.0 0.4 0.9 0.32 0.6 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 2.0 0.65 2.0 0.65 pair_coeff * * oxdna/hbond 0.0 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45 pair_coeff 1 4 oxdna/hbond 1.077 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45 pair_coeff 2 3 oxdna/hbond 1.077 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45 pair_coeff * * oxdna/xstk 47.5 0.575 0.675 0.495 0.655 2.25 0.791592653589793 0.58 1.7 1.0 0.68 1.7 1.0 0.68 1.5 0 0.65 1.7 0.875 0.68 1.7 0.875 0.68 pair_coeff * * oxdna/coaxstk 46.0 0.4 0.6 0.22 0.58 2.0 2.541592653589793 0.65 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 2.0 -0.65 2.0 -0.65 :pre [Description:] -The {oxdna} pair styles compute the pairwise-additive parts of the oxDNA force field -for coarse-grained modelling of DNA. The effective interaction between the nucleotides consists of potentials for the +The {oxdna} pair styles compute the pairwise-additive parts of the oxDNA force field +for coarse-grained modelling of DNA. The effective interaction between the nucleotides consists of potentials for the excluded volume interaction {oxdna/excv}, the stacking {oxdna/stk}, cross-stacking {oxdna/xstk} and coaxial stacking interaction {oxdna/coaxstk} as well as the hydrogen-bonding interaction {oxdna/hbond} between complementary pairs of nucleotides on opposite strands. -The exact functional form of the pair styles is rather complex, which manifests itself in the 144 coefficients -in the above example. The individual potentials consist of products of modulation factors, -which themselves are constructed from a number of more basic potentials -(Morse, Lennard-Jones, harmonic angle and distance) as well as quadratic smoothing and modulation terms. +The exact functional form of the pair styles is rather complex, which manifests itself in the 144 coefficients +in the above example. The individual potentials consist of products of modulation factors, +which themselves are constructed from a number of more basic potentials +(Morse, Lennard-Jones, harmonic angle and distance) as well as quadratic smoothing and modulation terms. We refer to "(Ouldridge-DPhil)"_#Ouldridge-DPhil1 and "(Ouldridge)"_#Ouldridge1 for a detailed description of the oxDNA force field. NOTE: These pair styles have to be used together with the related oxDNA bond style {oxdna/fene} for the connectivity of the phosphate backbone (see also documentation of "bond_style oxdna/fene"_bond_oxdna.html). With one exception the coefficients in the above example have to be kept fixed and cannot be changed without reparametrizing the entire model. -The exception is the first coefficient after {oxdna/stk} (T=0.1 in the above example). -When using a Langevin thermostat, e.g. through "fix langevin"_fix_langevin.html +The exception is the first coefficient after {oxdna/stk} (T=0.1 in the above example). +When using a Langevin thermostat, e.g. through "fix langevin"_fix_langevin.html or "fix nve/dotc/langevin"_fix_nve_dotc_langevin.html the temperature coefficients have to be matched to the one used in the fix. Example input and data files for DNA duplexes can be found in examples/USER/cgdna/examples/oxDNA/ and /oxDNA2/. A simple python setup tool which creates single straight or helical DNA strands, DNA duplexes or arrays of DNA duplexes can be found in examples/USER/cgdna/util/. A technical report with more information on the model, the structure of the input file, the setup tool and the performance of the LAMMPS-implementation of oxDNA can be found "here"_PDF/USER-CGDNA-overview.pdf. :line [Restrictions:] These pair styles can only be used if LAMMPS was built with the USER-CGDNA package and the MOLECULE and ASPHERE package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info on packages. [Related commands:] -"bond_style oxdna/fene"_bond_oxdna.html, "fix nve/dotc/langevin"_fix_nve_dotc_langevin.html, "pair_coeff"_pair_coeff.html, +"bond_style oxdna/fene"_bond_oxdna.html, "fix nve/dotc/langevin"_fix_nve_dotc_langevin.html, "pair_coeff"_pair_coeff.html, "bond_style oxdna2/fene"_bond_oxdna.html, "pair_style oxdna2/excv"_pair_oxdna2.html [Default:] none :line :link(Ouldridge-DPhil1) [(Ouldrigde-DPhil)] T.E. Ouldridge, Coarse-grained modelling of DNA and DNA self-assembly, DPhil. University of Oxford (2011). :link(Ouldridge1) [(Ouldridge)] T.E. Ouldridge, A.A. Louis, J.P.K. Doye, J. Chem. Phys. 134, 085101 (2011). diff --git a/doc/src/pair_oxdna2.txt b/doc/src/pair_oxdna2.txt index 1cc562d5f..1728a0bc7 100644 --- a/doc/src/pair_oxdna2.txt +++ b/doc/src/pair_oxdna2.txt @@ -1,102 +1,102 @@ "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 oxdna2/excv command :h3 pair_style oxdna2/stk command :h3 pair_style oxdna2/hbond command :h3 pair_style oxdna2/xstk command :h3 pair_style oxdna2/coaxstk command :h3 pair_style oxdna2/dh command :h3 [Syntax:] pair_style style1 :pre pair_coeff * * style2 args :pre style1 = {hybrid/overlay oxdna2/excv oxdna2/stk oxdna2/hbond oxdna2/xstk oxdna2/coaxstk oxdna2/dh} :ul style2 = {oxdna2/stk} or {oxdna2/dh} args = list of arguments for these two particular styles :ul {oxdna2/stk} args = T 6.0 0.4 0.9 0.32 0.6 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 2.0 0.65 2.0 0.65 T = temperature (oxDNA units, 0.1 = 300 K) {oxdna2/dh} args = T rhos qeff T = temperature (oxDNA units, 0.1 = 300 K) rhos = salt concentration (mole per litre) qeff = effective charge (elementary charges) :pre [Examples:] pair_style hybrid/overlay oxdna2/excv oxdna2/stk oxdna2/hbond oxdna2/xstk oxdna2/coaxstk oxdna2/dh pair_coeff * * oxdna2/excv 2.0 0.7 0.675 2.0 0.515 0.5 2.0 0.33 0.32 pair_coeff * * oxdna2/stk 0.1 6.0 0.4 0.9 0.32 0.6 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 2.0 0.65 2.0 0.65 pair_coeff * * oxdna2/hbond 0.0 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45 pair_coeff 1 4 oxdna2/hbond 1.0678 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45 pair_coeff 2 3 oxdna2/hbond 1.0678 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45 pair_coeff * * oxdna2/xstk 47.5 0.575 0.675 0.495 0.655 2.25 0.791592653589793 0.58 1.7 1.0 0.68 1.7 1.0 0.68 1.5 0 0.65 1.7 0.875 0.68 1.7 0.875 0.68 pair_coeff * * oxdna2/coaxstk 58.5 0.4 0.6 0.22 0.58 2.0 2.891592653589793 0.65 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 40.0 3.116592653589793 pair_coeff * * oxdna2/dh 0.1 1.0 0.815 :pre [Description:] -The {oxdna2} pair styles compute the pairwise-additive parts of the oxDNA force field -for coarse-grained modelling of DNA. The effective interaction between the nucleotides consists of potentials for the +The {oxdna2} pair styles compute the pairwise-additive parts of the oxDNA force field +for coarse-grained modelling of DNA. The effective interaction between the nucleotides consists of potentials for the excluded volume interaction {oxdna2/excv}, the stacking {oxdna2/stk}, cross-stacking {oxdna2/xstk} and coaxial stacking interaction {oxdna2/coaxstk}, electrostatic Debye-Hueckel interaction {oxdna2/dh} as well as the hydrogen-bonding interaction {oxdna2/hbond} between complementary pairs of nucleotides on opposite strands. -The exact functional form of the pair styles is rather complex. -The individual potentials consist of products of modulation factors, -which themselves are constructed from a number of more basic potentials -(Morse, Lennard-Jones, harmonic angle and distance) as well as quadratic smoothing and modulation terms. +The exact functional form of the pair styles is rather complex. +The individual potentials consist of products of modulation factors, +which themselves are constructed from a number of more basic potentials +(Morse, Lennard-Jones, harmonic angle and distance) as well as quadratic smoothing and modulation terms. We refer to "(Snodin)"_#Snodin and the original oxDNA publications "(Ouldridge-DPhil)"_#Ouldridge-DPhil2 and "(Ouldridge)"_#Ouldridge2 for a detailed description of the oxDNA2 force field. NOTE: These pair styles have to be used together with the related oxDNA2 bond style {oxdna2/fene} for the connectivity of the phosphate backbone (see also documentation of "bond_style oxdna2/fene"_bond_oxdna.html). Almost all coefficients in the above example have to be kept fixed and cannot be changed without reparametrizing the entire model. -Exceptions are the first coefficient after {oxdna2/stk} (T=0.1 in the above example) and the coefficients +Exceptions are the first coefficient after {oxdna2/stk} (T=0.1 in the above example) and the coefficients after {oxdna2/dh} (T=0.1, rhos=1.0, qeff=0.815 in the above example). When using a Langevin thermostat e.g. through "fix langevin"_fix_langevin.html or "fix nve/dotc/langevin"_fix_nve_dotc_langevin.html the temperature coefficients have to be matched to the one used in the fix. Example input and data files for DNA duplexes can be found in examples/USER/cgdna/examples/oxDNA/ and /oxDNA2/. A simple python setup tool which creates single straight or helical DNA strands, DNA duplexes or arrays of DNA duplexes can be found in examples/USER/cgdna/util/. A technical report with more information on the model, the structure of the input file, the setup tool and the performance of the LAMMPS-implementation of oxDNA can be found "here"_PDF/USER-CGDNA-overview.pdf. :line [Restrictions:] These pair styles can only be used if LAMMPS was built with the USER-CGDNA package and the MOLECULE and ASPHERE package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info on packages. [Related commands:] "bond_style oxdna2/fene"_bond_oxdna.html, "fix nve/dotc/langevin"_fix_nve_dotc_langevin.html, "pair_coeff"_pair_coeff.html, -"bond_style oxdna/fene"_bond_oxdna.html, "pair_style oxdna/excv"_pair_oxdna.html +"bond_style oxdna/fene"_bond_oxdna.html, "pair_style oxdna/excv"_pair_oxdna.html [Default:] none :line :link(Snodin) [(Snodin)] B.E. Snodin, F. Randisi, M. Mosayebi, et al., J. Chem. Phys. 142, 234901 (2015). :link(Ouldridge-DPhil2) [(Ouldrigde-DPhil)] T.E. Ouldridge, Coarse-grained modelling of DNA and DNA self-assembly, DPhil. University of Oxford (2011). :link(Ouldridge2) [(Ouldridge)] T.E. Ouldridge, A.A. Louis, J.P.K. Doye, J. Chem. Phys. 134, 085101 (2011). diff --git a/doc/src/pair_table_rx.txt b/doc/src/pair_table_rx.txt index d089a4f9d..f93af21da 100644 --- a/doc/src/pair_table_rx.txt +++ b/doc/src/pair_table_rx.txt @@ -1,241 +1,241 @@ "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 table/rx command :h3 [Syntax:] pair_style table style N ... :pre style = {lookup} or {linear} or {spline} or {bitmap} = method of interpolation N = use N values in {lookup}, {linear}, {spline} tables weighting = fractional or molecular (optional) :ul [Examples:] pair_style table/rx linear 1000 pair_style table/rx linear 1000 fractional pair_style table/rx linear 1000 molecular pair_coeff * * rxn.table ENTRY1 h2o h2o 10.0 pair_coeff * * rxn.table ENTRY1 1fluid 1fluid 10.0 pair_coeff * 3 rxn.table ENTRY1 h2o no2 10.0 :pre [Description:] Style {table/rx} is used in reaction DPD simulations,where the coarse-grained (CG) particles are composed of {m} species whose reaction rate kinetics are determined from a set of {n} reaction rate equations through the "fix rx"_fix_rx.html command. The species of one CG particle can interact with a species in a neighboring CG particle through a site-site interaction potential model. Style {table/rx} creates interpolation tables of length {N} from pair potential and force values listed in a file(s) as a function of distance. The files are read by the "pair_coeff"_pair_coeff.html command. The interpolation tables are created by fitting cubic splines to the file values and interpolating energy and force values at each of {N} distances. During a simulation, these tables are used to interpolate energy and force values as needed. The interpolation is done in one of 4 styles: {lookup}, {linear}, {spline}, or {bitmap}. For the {lookup} style, the distance between 2 atoms is used to find the nearest table entry, which is the energy or force. For the {linear} style, the pair distance is used to find 2 surrounding table values from which an energy or force is computed by linear interpolation. For the {spline} style, a cubic spline coefficients are computed and stored at each of the {N} values in the table. The pair distance is used to find the appropriate set of coefficients which are used to evaluate a cubic polynomial which computes the energy or force. For the {bitmap} style, the N means to create interpolation tables that are 2^N in length. The pair distance is used to index into the table via a fast bit-mapping technique "(Wolff)"_#Wolff and a linear interpolation is performed between adjacent table values. The following coefficients must be defined for each pair of atoms types via the "pair_coeff"_pair_coeff.html command as in the examples above. filename keyword species1 species2 cutoff (distance units) :ul The filename specifies a file containing tabulated energy and force values. The keyword specifies a section of the file. The cutoff is an optional coefficient. If not specified, the outer cutoff in the table itself (see below) will be used to build an interpolation table that extend to the largest tabulated distance. If specified, only file values up to the cutoff are used to create the interpolation table. The format of this file is described below. The species tags define the site-site interaction potential between two species contained within two different particles. The species tags must either correspond to the species defined in the reaction kinetics files specified with the "fix rx"_fix_rx.html command or they must correspond to the tag "1fluid", signifying interaction with a product species mixture determined through a one-fluid approximation. -The interaction potential is weighted by the geometric average of -either the mole fraction concentrations or the number of molecules -associated with the interacting coarse-grained particles (see the +The interaction potential is weighted by the geometric average of +either the mole fraction concentrations or the number of molecules +associated with the interacting coarse-grained particles (see the {fractional} or {molecular} weighting pair style options). The coarse-grained potential is stored before and after the reaction kinetics solver is applied, where the difference is defined to be the internal chemical energy (uChem). :line Here are some guidelines for using the pair_style table/rx command to best effect: Vary the number of table points; you may need to use more than you think to get good resolution. :ulb,l Always use the "pair_write"_pair_write.html command to produce a plot of what the final interpolated potential looks like. This can show up interpolation "features" you may not like. :l Start with the linear style; it's the style least likely to have problems. :l Use {N} in the pair_style command equal to the "N" in the tabulation file, and use the "RSQ" or "BITMAP" parameter, so additional interpolation is not needed. See discussion below. :l Make sure that your tabulated forces and tabulated energies are consistent (dE/dr = -F) along the entire range of r values. :l Use as large an inner cutoff as possible. This avoids fitting splines to very steep parts of the potential. :l :ule :line The format of a tabulated file is a series of one or more sections, defined as follows (without the parenthesized comments): # Morse potential for Fe (one or more comment or blank lines) :pre MORSE_FE (keyword is first text on line) N 500 R 1.0 10.0 (N, R, RSQ, BITMAP, FPRIME parameters) (blank) 1 1.0 25.5 102.34 (index, r, energy, force) 2 1.02 23.4 98.5 ... 500 10.0 0.001 0.003 :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. The first line begins with a keyword which identifies the section. The line can contain additional text, but the initial text must match the argument specified in the pair_coeff command. The next line lists (in any order) one or more parameters for the table. Each parameter is a keyword followed by one or more numeric values. The parameter "N" is required and its value is the number of table entries that follow. Note that this may be different than the {N} specified in the "pair_style table/rx"_pair_style.html command. Let Ntable = {N} in the pair_style command, and Nfile = "N" in the tabulated file. What LAMMPS does is a preliminary interpolation by creating splines using the Nfile tabulated values as nodal points. It uses these to interpolate as needed to generate energy and force values at Ntable different points. The resulting tables of length Ntable are then used as described above, when computing energy and force for individual pair distances. This means that if you want the interpolation tables of length Ntable to match exactly what is in the tabulated file (with effectively no preliminary interpolation), you should set Ntable = Nfile, and use the "RSQ" or "BITMAP" parameter. The internal table abscissa is RSQ (separation distance squared). All other parameters are optional. If "R" or "RSQ" or "BITMAP" does not appear, then the distances in each line of the table are used as-is to perform spline interpolation. In this case, the table values can be spaced in {r} uniformly or however you wish to position table values in regions of large gradients. If used, the parameters "R" or "RSQ" are followed by 2 values {rlo} and {rhi}. If specified, the distance associated with each energy and force value is computed from these 2 values (at high accuracy), rather than using the (low-accuracy) value listed in each line of the table. The distance values in the table file are ignored in this case. For "R", distances uniformly spaced between {rlo} and {rhi} are computed; for "RSQ", squared distances uniformly spaced between {rlo*rlo} and {rhi*rhi} are computed. If used, the parameter "BITMAP" is also followed by 2 values {rlo} and {rhi}. These values, along with the "N" value determine the ordering of the N lines that follow and what distance is associated with each. This ordering is complex, so it is not documented here, since this file is typically produced by the "pair_write"_pair_write.html command with its {bitmap} option. When the table is in BITMAP format, the "N" parameter in the file must be equal to 2^M where M is the value specified in the pair_style command. Also, a cutoff parameter cannot be used as an optional 3rd argument in the pair_coeff command; the entire table extent as specified in the file must be used. If used, the parameter "FPRIME" is followed by 2 values {fplo} and {fphi} which are the derivative of the force at the innermost and outermost distances listed in the table. These values are needed by the spline construction routines. If not specified by the "FPRIME" parameter, they are estimated (less accurately) by the first 2 and last 2 force values in the table. This parameter is not used by BITMAP tables. Following a blank line, the next N lines list the tabulated values. On each line, the 1st value is the index from 1 to N, the 2nd value is r (in distance units), the 3rd value is the energy (in energy units), and the 4th is the force (in force units). The r values must increase from one line to the next (unless the BITMAP parameter is specified). Note that one file can contain many sections, each with a tabulated potential. LAMMPS reads the file section by section until it finds one that matches the specified keyword. :line [Mixing, shift, table, tail correction, restart, rRESPA info]: This pair style does not support mixing. Thus, coefficients for all I,J pairs must be specified explicitly. The "pair_modify"_pair_modify.html shift, table, and tail options are not relevant for this pair style. This pair style writes the settings for the "pair_style table/rx" command to "binary restart files"_restart.html, so a pair_style 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, since it is tabulated in the potential files. Thus, pair_coeff commands do need to be specified in the restart input script. 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 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. [Related commands:] "pair_coeff"_pair_coeff.html [Default:] fractional weighting :line :link(Wolff) [(Wolff)] Wolff and Rudd, Comp Phys Comm, 120, 200-32 (1999). diff --git a/doc/src/python.txt b/doc/src/python.txt index e00b90234..c6538ded4 100644 --- a/doc/src/python.txt +++ b/doc/src/python.txt @@ -1,498 +1,498 @@ "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c :link(lws,http://lammps.sandia.gov) :link(ld,Manual.html) :link(lc,Section_commands.html#comm) :line python command :h3 [Syntax:] python func keyword args ... :pre func = name of Python function :ulb,l one or more keyword/args pairs must be appended :l keyword = {invoke} or {input} or {return} or {format} or {length} or {file} or {here} or {exists} or {source} {invoke} arg = none = invoke the previously defined Python function {input} args = N i1 i2 ... iN N = # of inputs to function i1,...,iN = value, SELF, or LAMMPS variable name value = integer number, floating point number, or string SELF = reference to LAMMPS itself which can be accessed by Python function variable = v_name, where name = name of LAMMPS variable, e.g. v_abc {return} arg = varReturn varReturn = v_name = LAMMPS variable name which return value of function will be assigned to {format} arg = fstring with M characters M = N if no return value, where N = # of inputs M = N+1 if there is a return value fstring = each character (i,f,s,p) corresponds in order to an input or return value 'i' = integer, 'f' = floating point, 's' = string, 'p' = SELF {length} arg = Nlen Nlen = max length of string returned from Python function {file} arg = filename filename = file of Python code, which defines func {here} arg = inline inline = one or more lines of Python code which defines func must be a single argument, typically enclosed between triple quotes {exists} arg = none = Python code has been loaded by previous python command {source} arg = {filename} or {inline} filename = file of Python code which will be executed immediately inline = one or more lines of Python code which will be executed immediately must be a single argument, typically enclosed between triple quotes :pre :ule [Examples:] python pForce input 2 v_x 20.0 return v_f format fff file force.py python pForce invoke :pre python factorial input 1 myN return v_fac format ii here """ def factorial(n): if n == 1: return n return n * factorial(n-1) """ :pre python loop input 1 SELF return v_value format pf here """ def loop(lmpptr,N,cut0): from lammps import lammps lmp = lammps(ptr=lmpptr) :pre # loop N times, increasing cutoff each time :pre for i in range(N): cut = cut0 + i*0.1 lmp.set_variable("cut",cut) # set a variable in LAMMPS lmp.command("pair_style lj/cut $\{cut\}") # LAMMPS commands lmp.command("pair_coeff * * 1.0 1.0") lmp.command("run 100") """ :pre [Description:] Define a Python function or execute a previously defined function or execute some arbitrary python code. Arguments, including LAMMPS variables, can be passed to the function from the LAMMPS input script and a value returned by the Python function to a LAMMPS variable. The Python code for the function can be included directly in the input script or in a separate Python file. The function can be standard Python code or it can make "callbacks" to LAMMPS through its library interface to query or set internal values within LAMMPS. This is a powerful mechanism for performing complex operations in a LAMMPS input script that are not possible with the simple input script and variable syntax which LAMMPS defines. Thus your input script can operate more like a true programming language. Use of this command requires building LAMMPS with the PYTHON package which links to the Python library so that the Python interpreter is embedded in LAMMPS. More details about this process are given below. There are two ways to invoke a Python function once it has been defined. One is using the {invoke} keyword. The other is to assign the function to a "python-style variable"_variable.html defined in your input script. Whenever the variable is evaluated, it will execute the Python function to assign a value to the variable. Note that variables can be evaluated in many different ways within LAMMPS. They can be substituted for directly in an input script. Or they can be passed to various commands as arguments, so that the variable is evaluated during a simulation run. A broader overview of how Python can be used with LAMMPS is given in "Section 11"_Section_python.html. There is an examples/python directory which illustrates use of the python command. :line The {func} setting specifies the name of the Python function. The code for the function is defined using the {file} or {here} keywords as explained below. In case of the {source} keyword, the name of the function is ignored. If the {invoke} keyword is used, no other keywords can be used, and a previous python command must have defined the Python function referenced by this command. This invokes the Python function with the previously defined arguments and return value processed as explained below. You can invoke the function as many times as you wish in your input script. If the {source} keyword is used, no other keywords can be used. The argument can be a filename or a string with python commands, either on a single line enclosed in quotes, or as multiple lines enclosed in triple quotes. These python commands will be passed to the python interpreter and executed immediately without registering a python function for future execution. The {input} keyword defines how many arguments {N} the Python function expects. If it takes no arguments, then the {input} keyword should not be used. Each argument can be specified directly as a value, e.g. 6 or 3.14159 or abc (a string of characters). The type of each argument is specified by the {format} keyword as explained below, so that Python will know how to interpret the value. If the word SELF is used for an argument it has a special meaning. A pointer is passed to the Python function which it converts into a reference to LAMMPS itself. This enables the function to call back to LAMMPS through its library interface as explained below. This allows the Python function to query or set values internal to LAMMPS which can affect the subsequent execution of the input script. A LAMMPS variable can also be used as an argument, specified as v_name, where "name" is the name of the variable. Any style of LAMMPS variable can be used, as defined by the "variable"_variable.html command. Each time the Python function is invoked, the LAMMPS variable is evaluated and its value is passed to the Python function. The {return} keyword is only needed if the Python function returns a value. The specified {varReturn} must be of the form v_name, where "name" is the name of a python-style LAMMPS variable, defined by the "variable"_variable.html command. The Python function can return a numeric or string value, as specified by the {format} keyword. As explained on the "variable"_variable.html doc page, the definition of a python-style variable associates a Python function name with the variable. This must match the {func} setting for this command. For 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 in the input script so long as both are specified before the Python function is invoked for the first time. The {format} keyword must be used if the {input} or {return} keyword is used. It defines an {fstring} with M characters, where M = sum of number of inputs and outputs. The order of characters corresponds to the N inputs, followed by the return value (if it exists). Each character must be one of the following: "i" for integer, "f" for floating point, "s" for string, or "p" for SELF. Each character defines the type of the corresponding input or output value of the Python function and affects the type conversion that is performed internally as data is passed back and forth between LAMMPS and Python. Note that it is permissible to use a "python-style variable"_variable.html in a LAMMPS command that allows for an equal-style variable as an argument, but only if the output of the Python function is flagged as a numeric value ("i" or "f") via the {format} keyword. If the {return} keyword is used and the {format} keyword specifies the output as a string, then the default maximum length of that string is 63 characters (64-1 for the string terminator). If you want to return a longer string, the {length} keyword can be specified with its {Nlen} value set to a larger number (the code allocates space for Nlen+1 to include the string terminator). If the Python function generates a string longer than the default 63 or the specified {Nlen}, it will be truncated. :line Either the {file}, {here}, or {exists} keyword must be used, but only one of them. These keywords specify what Python code to load into the Python interpreter. The {file} keyword gives the name of a file, which should end with a ".py" suffix, which contains Python code. The code will be immediately loaded into and run in the "main" module of the Python interpreter. Note that Python code which contains a function definition does not "execute" the function when it is run; it simply defines the function so that it can be invoked later. The {here} keyword does the same thing, except that the Python code follows as a single argument to the {here} keyword. This can be done using triple quotes as delimiters, as in the examples above. This allows Python code to be listed verbatim in your input script, with proper indentation, blank lines, and comments, as desired. See "Section 3.2"_Section_commands.html#cmd_2, for an explanation of how triple quotes can be used as part of input script syntax. The {exists} keyword takes no argument. It means that Python code containing the required Python function defined by the {func} setting, is assumed to have been previously loaded by another python command. Note that the Python code that is loaded and run must contain a function with the specified {func} name. To operate properly when later invoked, the function code must match the {input} and {return} and {format} keywords specified by the python command. Otherwise Python will generate an error. :line This section describes how Python code can be written to work with LAMMPS. Whether you load Python code from a file or directly from your input script, via the {file} and {here} keywords, the code can be identical. It must be indented properly as Python requires. It can contain comments or blank lines. If the code is in your input script, it cannot however contain triple-quoted Python strings, since that will conflict with the triple-quote parsing that the LAMMPS input script performs. All the Python code you specify via one or more python commands is loaded into the Python "main" module, i.e. __main__. The code can define global variables or statements that are outside of function definitions. It can contain multiple functions, only one of which matches the {func} setting in the python command. This means you can use the {file} keyword once to load several functions, and the {exists} keyword thereafter in subsequent python commands to access the other functions previously loaded. A Python function you define (or more generally, the code you load) can import other Python modules or classes, it can make calls to other system functions or functions you define, and it can access or modify global variables (in the "main" module) which will persist between successive function calls. The latter can be useful, for example, to prevent a function from being invoke multiple times per timestep by different commands in a LAMMPS input script that access the returned python-style variable associated with the function. For example, consider this function loaded with two global variables defined outside the function: nsteplast = -1 nvaluelast = 0 :pre def expensive(nstep): global nsteplast,nvaluelast if nstep == nsteplast: return nvaluelast nsteplast = nstep # perform complicated calculation nvalue = ... nvaluelast = nvalue return nvalue :pre Nsteplast stores the previous timestep the function was invoked (passed as an argument to the function). Nvaluelast stores the return value computed on the last function invocation. If the function is invoked again on the same timestep, the previous value is simply returned, without re-computing it. The "global" statement inside the Python function allows it to overwrite the global variables. Note that if you load Python code multiple times (via multiple python commands), you can overwrite previously loaded variables and functions if you are not careful. E.g. if the code above were loaded twice, the global variables would be re-initialized, which might not be what you want. Likewise, if a function with the same name exists in two chunks of Python code you load, the function loaded second will override the function loaded first. It's important to realize that if you are running LAMMPS in parallel, each MPI task will load the Python interpreter and execute a local copy of the Python function(s) you define. There is no connection between the Python interpreters running on different processors. This implies three important things. First, if you put a print statement in your Python function, you will see P copies of the output, when running on P processors. If the prints occur at (nearly) the same time, the P copies of the output may be mixed together. Welcome to the world of parallel programming and debugging. Second, if your Python code loads modules that are not pre-loaded by the Python library, then it will load the module from disk. This may be a bottleneck if 1000s of processors try to load a module at the same time. On some large supercomputers, loading of modules from disk by Python may be disabled. In this case you would need to pre-build a Python library that has the required modules pre-loaded and link LAMMPS with that library. Third, if your Python code calls back to LAMMPS (discussed in the next section) and causes LAMMPS to perform an MPI operation requires global communication (e.g. via MPI_Allreduce), such as computing the global temperature of the system, then you must insure all your Python functions (running independently on different processors) call back to LAMMPS. Otherwise the code may hang. :line Your Python function can "call back" to LAMMPS through its library interface, if you use the SELF input to pass Python a pointer to LAMMPS. The mechanism for doing this in your Python function is as follows: def foo(lmpptr,...): from lammps import lammps lmp = lammps(ptr=lmpptr) lmp.command('print "Hello from inside Python"') ... :pre The function definition must include a variable (lmpptr in this case) which corresponds to SELF in the python command. The first line of the function imports the Python module lammps.py in the python dir of the distribution. The second line creates a Python object "lmp" which wraps the instance of LAMMPS that called the function. The "ptr=lmpptr" argument is what makes that happen. The third line invokes the command() function in the LAMMPS library interface. It takes a single string argument which is a LAMMPS input script command for LAMMPS to execute, the same as if it appeared in your input script. In this case, LAMMPS should output Hello from inside Python :pre to the screen and log file. Note that since the LAMMPS print command itself takes a string in quotes as its argument, the Python string must be delimited with a different style of quotes. "Section 11.7"_Section_python.html#py_7 describes the syntax for how Python wraps the various functions included in the LAMMPS library interface. A more interesting example is in the examples/python/in.python script which loads and runs the following function from examples/python/funcs.py: def loop(N,cut0,thresh,lmpptr): print "LOOP ARGS",N,cut0,thresh,lmpptr from lammps import lammps lmp = lammps(ptr=lmpptr) natoms = lmp.get_natoms() :pre for i in range(N): cut = cut0 + i*0.1 :pre lmp.set_variable("cut",cut) # set a variable in LAMMPS lmp.command("pair_style lj/cut $\{cut\}") # LAMMPS command #lmp.command("pair_style lj/cut %d" % cut) # LAMMPS command option :pre lmp.command("pair_coeff * * 1.0 1.0") # ditto lmp.command("run 10") # ditto pe = lmp.extract_compute("thermo_pe",0,0) # extract total PE from LAMMPS print "PE",pe/natoms,thresh if pe/natoms < thresh: return :pre with these input script commands: python loop input 4 10 1.0 -4.0 SELF format iffp file funcs.py python loop invoke :pre This has the effect of looping over a series of 10 short runs (10 timesteps each) where the pair style cutoff is increased from a value of 1.0 in distance units, in increments of 0.1. The looping stops when the per-atom potential energy falls below a threshold of -4.0 in energy units. More generally, Python can be used to implement a loop with complex logic, much more so than can be created using the LAMMPS "jump"_jump.html and "if"_if.html commands. Several LAMMPS library functions are called from the loop function. Get_natoms() returns the number of atoms in the simulation, so that it can be used to normalize the potential energy that is returned by extract_compute() for the "thermo_pe" compute that is defined by default for LAMMPS thermodynamic output. Set_variable() sets the value of a string variable defined in LAMMPS. This library function is a useful way for a Python function to return multiple values to LAMMPS, more than the single value that can be passed back via a return statement. This cutoff value in the "cut" variable is then substituted (by LAMMPS) in the pair_style command that is executed next. Alternatively, the "LAMMPS command option" line could be used in place of the 2 preceding lines, to have Python insert the value into the LAMMPS command string. NOTE: When using the callback mechanism just described, recognize that there are some operations you should not attempt because LAMMPS cannot execute them correctly. If the Python function is invoked between runs in the LAMMPS input script, then it should be OK to invoke any LAMMPS input script command via the library interface command() or file() functions, so long as the command would work if it were executed in the LAMMPS input script directly at the same point. However, a Python function can also be invoked during a run, whenever an associated LAMMPS variable it is assigned to is evaluated. If the variable is an input argument to another LAMMPS command (e.g. "fix setforce"_fix_setforce.html), then the Python function will be invoked inside the class for that command, in one of its methods that is invoked in the middle of a timestep. You cannot execute arbitrary input script commands from the Python function (again, via the command() or file() functions) at that point in the run and expect it to work. Other library functions such as those that invoke computes or other variables may have hidden side effects as well. In these cases, LAMMPS has no simple way to check that something illogical is being attempted. The same applies to Python functions called during a simulation run at each time step using "fix python"_fix_python.html. :line If you run Python code directly on your workstation, either interactively or by using Python to launch a Python script stored in a file, and your code has an error, you will typically see informative error messages. That is not the case when you run Python code from LAMMPS using an embedded Python interpreter. The code will typically fail silently. LAMMPS will catch some errors but cannot tell you where in the Python code the problem occurred. For example, if the Python code cannot be loaded and run because it has syntax or other logic errors, you may get an error from Python pointing to the offending line, or you may get one of these generic errors from LAMMPS: Could not process Python file Could not process Python string :pre When the Python function is invoked, if it does not return properly, you will typically get this generic error from LAMMPS: Python function evaluation failed :pre Here are three suggestions for debugging your Python code while running it under LAMMPS. First, don't run it under LAMMPS, at least to start with! Debug it using plain Python. Load and invoke your function, pass it arguments, check return values, etc. Second, add Python print statements to the function to check how far it gets and intermediate values it calculates. See the discussion above about printing from Python when running in parallel. Third, use Python exception handling. For example, say this statement in your Python function is failing, because you have not initialized the variable foo: foo += 1 :pre If you put one (or more) statements inside a "try" statement, like this: import exceptions print "Inside simple function" try: foo += 1 # one or more statements here except Exception, e: print "FOO error:",e :pre then you will get this message printed to the screen: FOO error: local variable 'foo' referenced before assignment :pre If there is no error in the try statements, then nothing is printed. Either way the function continues on (unless you put a return or sys.exit() in the except clause). :line [Restrictions:] This command is part of the PYTHON package. It is only enabled if LAMMPS was built with that package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. Building LAMMPS with the PYTHON package will link LAMMPS with the Python library on your system. Settings to enable this are in the lib/python/Makefile.lammps file. See the lib/python/README file for information on those settings. If you use Python code which calls back to LAMMPS, via the SELF input argument explained above, there is an extra step required when building LAMMPS. LAMMPS must also be built as a shared library and your Python function must be able to to load the Python module in python/lammps.py that wraps the LAMMPS library interface. These are the same steps required to use Python by itself to wrap LAMMPS. Details on these steps are explained in "Section python"_Section_python.html. Note that it is important that the stand-alone LAMMPS executable and the LAMMPS shared library be consistent (built from the same source code files) in order for this to work. If the two have been built at different times using -different source files, problems may occur. +different source files, problems may occur. [Related commands:] "shell"_shell.html, "variable"_variable.html, "fix python"_fix_python.html [Default:] none diff --git a/doc/src/run_style.txt b/doc/src/run_style.txt index 0e3c1a939..a67899420 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) + n1, n2, ... = loop factors 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} {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) {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) {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 4 2 2 2 bond 1 dihedral 2 inner 3 5.0 6.0 outer 4 kspace 4 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 integration, 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 specify 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 thermodynamic 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 beyond 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 assignment 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)"_#Tuckerman3 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 mutually 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 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(Tuckerman3) [(Tuckerman)] Tuckerman, Berne and Martyna, J Chem Phys, 97, p 1990 (1992). diff --git a/doc/src/tutorial_github.txt b/doc/src/tutorial_github.txt index d6ec22589..3e10b821a 100644 --- a/doc/src/tutorial_github.txt +++ b/doc/src/tutorial_github.txt @@ -1,383 +1,383 @@ "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 GitHub tutorial :h3 [written by Stefan Paquay] :line This document describes the process of how to use GitHub to integrate changes or additions you have made to LAMMPS into the official LAMMPS distribution. It uses the process of updating this very tutorial as an example to describe the individual steps and options. You need to be familiar with git and you may want to have a look at the "Git book"_http://git-scm.com/book/ to reacquaint yourself with some of the more advanced git features used below. As of fall 2016, submitting contributions to LAMMPS via pull requests on GitHub is the preferred option for integrating contributed features or improvements to LAMMPS, as it significantly reduces the amount of work required by the LAMMPS developers. Consequently, creating a pull request will increase your chances to have your contribution included and will reduce the time until the integration is complete. For more information on the requirements to have your code included into LAMMPS please see "Section 10.15"_Section_modify.html#mod_15 :line [Making an account] First of all, you need a GitHub account. This is fairly simple, just go to "GitHub"_https://github.com and create an account by clicking the "Sign up for GitHub" button. Once your account is created, you can sign in by clicking the button in the top left and filling in your username or e-mail address and password. :line [Forking the repository] To get changes into LAMMPS, you need to first fork the `lammps/lammps` repository on GitHub. At the time of writing, {master} is the preferred target branch. Thus go to "LAMMPS on GitHub"_https://github.com/lammps/lammps and make sure branch is set to "master", as shown in the figure below. :c,image(JPG/tutorial_branch.png) If it is not, use the button to change it to {master}. Once it is, use the fork button to create a fork. :c,image(JPG/tutorial_fork.png) This will create a fork (which is essentially a copy, but uses less resources) of the LAMMPS repository under your own GitHub account. You can make changes in this fork and later file {pull requests} to allow the upstream repository to merge changes from your own fork into the one we just forked from (or others that were forked from the same repository). At the same time, you can set things up, so you can include changes from upstream into your repository and thus keep it in sync with the ongoing LAMMPS development. :line [Adding changes to your own fork] Additions to the upstream version of LAMMPS are handled using {feature branches}. For every new feature, a so-called feature branch is created, which contains only those modification relevant to one specific feature. For example, adding a single fix would consist of creating a branch with only the fix header and source file and nothing else. It is explained in more detail here: "feature branch workflow"_https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow. [Feature branches] First of all, create a clone of your version on github on your local machine via HTTPS: $ git clone https://github.com//lammps.git :pre or, if you have set up your GitHub account for using SSH keys, via SSH: $ git clone git@github.com:/lammps.git :pre - + You can find the proper URL by clicking the "Clone or download"-button: :c,image(JPG/tutorial_https_block.png) The above command copies ("clones") the git repository to your local machine to a directory with the name you chose. If none is given, it will default to "lammps". Typical names are "mylammps" or something similar. You can use this local clone to make changes and test them without interfering with the repository on Github. To pull changes from upstream into this copy, you can go to the directory and use git pull: $ cd mylammps $ git checkout master $ git pull https://github.com/lammps/lammps :pre You can also add this URL as a remote: $ git remote add lammps_upstream https://www.github.com/lammps/lammps :pre At this point, you typically make a feature branch from the updated master branch for the feature you want to work on. This tutorial contains the workflow that updated this tutorial, and hence we will call the branch "github-tutorial-update": $ git checkout -b github-tutorial-update master :pre Now that we have changed branches, we can make our changes to our local repository. Just remember that if you want to start working on another, unrelated feature, you should switch branches! [After changes are made] After everything is done, add the files to the branch and commit them: $ git add doc/src/tutorial_github.txt $ git add doc/src/JPG/tutorial*.png :pre IMPORTANT NOTE: Do not use {git commit -a} (or {git add -A}). The -a flag (or -A flag) will automatically include _all_ modified or new files and that is rarely the behavior you want. It can easily lead to accidentally adding unrelated and unwanted changes into the repository. Instead it is preferable to explicitly use {git add}, {git rm}, {git mv} for adding, removing, renaming individual files, respectively, and then {git commit} to finalize the commit. Carefully check all pending changes with {git status} before committing them. If you find doing this on the command line too tedious, consider using a GUI, for example the one included in git distributions written in Tk, i.e. use {git gui} (on some Linux distributions it may be required to install an additional package to use it). After adding all files, the change set can be committed with some useful message that explains the change. $ git commit -m 'Finally updated the github tutorial' :pre After the commit, the changes can be pushed to the same branch on GitHub: $ git push :pre Git will ask you for your user name and password on GitHub if you have not configured anything. If your local branch is not present on Github yet, it will ask you to add it by running $ git push --set-upstream origin github-tutorial-update :pre If you correctly type your user name and password, the feature branch should be added to your fork on GitHub. If you want to make really sure you push to the right repository (which is good practice), you can provide it explicitly: $ git push origin :pre or using an explicit URL: $ git push git@github.com:Pakketeretet2/lammps.git :pre :line [Filing a pull request] Up to this point in the tutorial, all changes were to {your} clones of LAMMPS. Eventually, however, you want this feature to be included into the official LAMMPS version. To do this, you will want to file a pull request by clicking on the "New pull request" button: :c,image(JPG/tutorial_new_pull_request.png) Make sure that the current branch is set to the correct one, which, in this case, is "github-tutorial-update". If done correctly, the only changes you will see are those that were made on this branch. This will open up a new window that lists changes made to the repository. If you are just adding new files, there is not much to do, but I suppose merge conflicts are to be resolved here if there are changes in existing files. If all changes can automatically be merged, green text at the top will say so and you can click the "Create pull request" button, see image. :c,image(JPG/tutorial_create_new_pull_request1.png) Before creating the pull request, make sure the short title is accurate and add a comment with details about your pull request. Here you write what your modifications do and why they should be incorporated upstream. Note the checkbox that says "Allow edits from maintainers". This is checked by default checkbox (although in my version of Firefox, only the checkmark is visible): :c,image(JPG/tutorial_edits_maintainers.png) If it is checked, maintainers can immediately add their own edits to the pull request. This helps the inclusion of your branch significantly, as simple/trivial changes can be added directly to your pull request branch by the LAMMPS maintainers. The alternative would be that they make changes on their own version of the branch and file a reverse pull request to you. Just leave this box checked unless you have a very good reason not to. Now just write some nice comments and click on "Create pull request". :c,image(JPG/tutorial_create_new_pull_request2.png) :line [After filing a pull request] NOTE: When you submit a pull request (or ask for a pull request) for the first time, you will receive an invitation to become a LAMMPS project collaborator. Please accept this invite as being a collaborator will simplify certain administrative tasks and will probably speed up the merging of your feature, too. You will notice that after filing the pull request, some checks are performed automatically: :c,image(JPG/tutorial_automated_checks.png) If all is fine, you will see this: :c,image(JPG/tutorial_automated_checks_passed.png) If any of the checks are failing, your pull request will not be processed, as your changes may break compilation for certain configurations or may not merge cleanly. It is your responsibility to remove the reason(s) for the failed test(s). If you need help with this, please contact the LAMMPS developers by adding a comment explaining your problems with resolving the failed tests. A few further interesting things (can) happen to pull requests before they are included. [Additional changes] First of all, any additional changes you push into your branch in your repository will automatically become part of the pull request: :c,image(JPG/tutorial_additional_changes.png) This means you can add changes that should be part of the feature after filing the pull request, which is useful in case you have forgotten them, or if a developer has requested that something needs to be changed before the feature can be accepted into the official LAMMPS version. After each push, the automated checks are run again. [Assignees] There is an assignee label for pull requests. If the request has not been reviewed by any developer yet, it is not assigned to anyone. After revision, a developer can choose to assign it to either a) you, b) a LAMMPS developer (including him/herself) or c) Steve Plimpton (sjplimp). Case a) happens if changes are required on your part :ulb,l Case b) means that at the moment, it is being tested and reviewed by a LAMMPS developer with the expectation that some changes would be required. After the review, the developer can choose to implement changes directly or suggest them to you. :l Case c) means that the pull request has been assigned to the lead developer Steve Plimpton and means it is considered ready for merging. :ule,l In this case, Axel assigned the tutorial to Steve: :c,image(JPG/tutorial_steve_assignee.png) [Edits from LAMMPS maintainers] If you allowed edits from maintainers (the default), any LAMMPS maintainer can add changes to your pull request. In this case, both Axel and Richard made changes to the tutorial: :c,image(JPG/tutorial_changes_others.png) [Reverse pull requests] Sometimes, however, you might not feel comfortable having other people push changes into your own branch, or maybe the maintainers are not sure their idea was the right one. In such a case, they can make changes, reassign you as the assignee, and file a "reverse pull request", i.e. file a pull request in your GitHub repository to include changes in the branch, that you have submitted as a pull request yourself. In that case, you can choose to merge their changes back into your branch, possibly make additional changes or corrections and proceed from there. It looks something like this: :c,image(JPG/tutorial_reverse_pull_request.png) For some reason, the highlighted button didn't work in my case, but I can go to my own repository and merge the pull request from there: :c,image(JPG/tutorial_reverse_pull_request2.png) Be sure to check the changes to see if you agree with them by clicking on the tab button: :c,image(JPG/tutorial_reverse_pull_request3.png) In this case, most of it is changes in the markup and a short rewrite of Axel's explanation of the "git gui" and "git add" commands. :c,image(JPG/tutorial_reverse_pull_request4.png) Because the changes are OK with us, we are going to merge by clicking on "Merge pull request". After a merge it looks like this: :c,image(JPG/tutorial_reverse_pull_request5.png) Now, since in the meantime our local text for the tutorial also changed, we need to pull Axel's change back into our branch, and merge them: $ git add tutorial_github.txt $ git add JPG/tutorial_reverse_pull_request*.png $ git commit -m "Updated text and images on reverse pull requests" $ git pull :pre In this case, the merge was painless because git could auto-merge: :c,image(JPG/tutorial_reverse_pull_request6.png) With Axel's changes merged in and some final text updates, our feature branch is now perfect as far as we are concerned, so we are going to commit and push again: $ git add tutorial_github.txt $ git add JPG/tutorial_reverse_pull_request6.png $ git commit -m "Merged Axel's suggestions and updated text" $ git push git@github.com:Pakketeretet2/lammps :pre This merge also shows up on the lammps Github page: :c,image(JPG/tutorial_reverse_pull_request7.png) :line [After a merge] When everything is fine, the feature branch is merged into the master branch: :c,image(JPG/tutorial_merged.png) Now one question remains: What to do with the feature branch that got merged into upstream? It is in principle safe to delete them from your own fork. This helps keep it a bit more tidy. Note that you first have to switch to another branch! $ git checkout master $ git pull master $ git branch -d github-tutorial-update :pre If you do not pull first, it is not really a problem but git will warn you at the next statement that you are deleting a local branch that was not yet fully merged into HEAD. This is because git does not yet know your branch just got merged into LAMMPS upstream. If you first delete and then pull, everything should still be fine. Finally, if you delete the branch locally, you might want to push this to your remote(s) as well: $ git push origin :github-tutorial-update :pre [Recent changes in the workflow] Some changes to the workflow are not captured in this tutorial. For example, in addition to the master branch, to which all new features should be submitted, there is now also an "unstable" and a "stable" branch; these have the same content as "master", but are only updated after a patch release or stable release was made. Furthermore, the naming of the patches now follow the pattern "patch_" to simplify comparisons between releases. Finally, all patches and submissions are subject to automatic testing and code checks to make sure they at the very least compile. diff --git a/doc/src/tutorial_pylammps.txt b/doc/src/tutorial_pylammps.txt index 0b4fb32ed..78cdd241f 100644 --- a/doc/src/tutorial_pylammps.txt +++ b/doc/src/tutorial_pylammps.txt @@ -1,463 +1,463 @@ "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 PyLammps Tutorial :h1 Overview :h2 PyLammps is a Python wrapper class which can be created on its own or use an existing lammps Python object. It creates a simpler, Python-like interface to common LAMMPS functionality. Unlike the original flat C-types interface, it exposes a discoverable API. It no longer requires knowledge of the underlying C++ code implementation. Finally, the IPyLammps wrapper builds on top of PyLammps and adds some additional features for IPython integration into IPython notebooks, e.g. for embedded visualization output from dump/image. Comparison of lammps and PyLammps interfaces :h3 lammps.lammps :h4 uses C-Types direct memory access to native C++ data provides functions to send and receive data to LAMMPS requires knowledge of how LAMMPS internally works (C pointers, etc) :ul lammps.PyLammps :h4 higher-level abstraction built on top of original C-Types interface manipulation of Python objects -communication with LAMMPS is hidden from API user +communication with LAMMPS is hidden from API user shorter, more concise Python better IPython integration, designed for quick prototyping :ul Quick Start :h2 System-wide Installation :h3 Step 1: Building LAMMPS as a shared library :h4 To use LAMMPS inside of Python it has to be compiled as shared library. This library is then loaded by the Python interface. In this example, we use the Make.py utility to create a Makefile with C++ exceptions, PNG, JPEG and FFMPEG output support enabled. Finally, we also enable the MOLECULE package and compile using the generated {auto} Makefile. cd $LAMMPS_DIR/src :pre # generate custom Makefile python Make.py -jpg -png -s ffmpeg exceptions -m mpi -a file :pre # add packages if necessary make yes-MOLECULE :pre # compile shared library using Makefile make mode=shlib auto :pre Step 2: Installing the LAMMPS Python package :h4 PyLammps is part of the lammps Python package. To install it simply install that package into your current Python installation. cd $LAMMPS_DIR/python python install.py :pre NOTE: Recompiling the shared library requires reinstalling the Python package Installation inside of a virtualenv :h3 You can use virtualenv to create a custom Python environment specifically tuned for your workflow. Benefits of using a virtualenv :h4 isolation of your system Python installation from your development installation installation can happen in your user directory without root access (useful for HPC clusters) installing packages through pip allows you to get newer versions of packages than e.g., through apt-get or yum package managers (and without root access) you can even install specific old versions of a package if necessary :ul [Prerequisite (e.g. on Ubuntu)] apt-get install python-virtualenv :pre Creating a virtualenv with lammps installed :h4 # create virtualenv name 'testing' :pre # activate 'testing' environment source testing/bin/activate :pre # install LAMMPS package in virtualenv (testing) cd $LAMMPS_DIR/python (testing) python install.py :pre # install other useful packages (testing) pip install matplotlib jupyter mpi4py :pre ... :pre # return to original shell (testing) deactivate :pre Creating a new instance of PyLammps :h2 To create a PyLammps object you need to first import the class from the lammps module. By using the default constructor, a new {lammps} instance is created. from lammps import PyLammps L = PyLammps() :pre You can also initialize PyLammps on top of this existing {lammps} object: from lammps import lammps, PyLammps lmp = lammps() L = PyLammps(ptr=lmp) :pre Commands :h2 Sending a LAMMPS command with the existing library interfaces is done using the command method of the lammps object instance. For instance, let's take the following LAMMPS command: region box block 0 10 0 5 -0.5 0.5 :pre In the original interface this command can be executed with the following Python code if {L} was a lammps instance: L.command("region box block 0 10 0 5 -0.5 0.5") :pre With the PyLammps interface, any command can be split up into arbitrary parts separated by whitespace, passed as individual arguments to a region method. L.region("box block", 0, 10, 0, 5, -0.5, 0.5) :pre Note that each parameter is set as Python literal floating-point number. In the PyLammps interface, each command takes an arbitrary parameter list and transparently merges it to a single command string, separating individual parameters by whitespace. The benefit of this approach is avoiding redundant command calls and easier parameterization. In the original interface parametrization needed to be done manually by creating formatted strings. L.command("region box block %f %f %f %f %f %f" % (xlo, xhi, ylo, yhi, zlo, zhi)) :pre In contrast, methods of PyLammps accept parameters directly and will convert them automatically to a final command string. L.region("box block", xlo, xhi, ylo, yhi, zlo, zhi) :pre System state :h2 In addition to dispatching commands directly through the PyLammps object, it also provides several properties which allow you to query the system state. :dlb L.system :dt Is a dictionary describing the system such as the bounding box or number of atoms :dd L.system.xlo, L.system.xhi :dt bounding box limits along x-axis :dd L.system.ylo, L.system.yhi :dt bounding box limits along y-axis :dd L.system.zlo, L.system.zhi :dt bounding box limits along z-axis :dd L.communication :dt configuration of communication subsystem, such as the number of threads or processors :dd L.communication.nthreads :dt number of threads used by each LAMMPS process :dd L.communication.nprocs :dt number of MPI processes used by LAMMPS :dd L.fixes :dt List of fixes in the current system :dd L.computes :dt List of active computes in the current system :dd L.dump :dt List of active dumps in the current system :dd L.groups :dt List of groups present in the current system :dd :dle Working with LAMMPS variables :h2 LAMMPS variables can be both defined and accessed via the PyLammps interface. To define a variable you can use the "variable"_variable.html command: L.variable("a index 2") :pre A dictionary of all variables is returned by L.variables you can access an individual variable by retrieving a variable object from the L.variables dictionary by name a = L.variables\['a'\] :pre The variable value can then be easily read and written by accessing the value property of this object. print(a.value) a.value = 4 :pre Retrieving the value of an arbitrary LAMMPS expressions :h2 LAMMPS expressions can be immediately evaluated by using the eval method. The passed string parameter can be any expression containing global thermo values, variables, compute or fix data. result = L.eval("ke") # kinetic energy result = L.eval("pe") # potential energy :pre result = L.eval("v_t/2.0") :pre Accessing atom data :h2 All atoms in the current simulation can be accessed by using the L.atoms list. Each element of this list is an object which exposes its properties (id, type, position, velocity, force, etc.). # access first atom L.atoms\[0\].id L.atoms\[0\].type :pre # access second atom L.atoms\[1\].position L.atoms\[1\].velocity L.atoms\[1\].force :pre Some properties can also be used to set: # set position in 2D simulation L.atoms\[0\].position = (1.0, 0.0) :pre # set position in 3D simulation L.atoms\[0\].position = (1.0, 0.0, 1.) :pre Evaluating thermo data :h2 Each simulation run usually produces thermo output based on system state, computes, fixes or variables. The trajectories of these values can be queried after a run via the L.runs list. This list contains a growing list of run data. The first element is the output of the first run, the second element that of the second run. L.run(1000) L.runs\[0\] # data of first 1000 time steps :pre L.run(1000) L.runs\[1\] # data of second 1000 time steps :pre Each run contains a dictionary of all trajectories. Each trajectory is accessible through its thermo name: L.runs\[0\].step # list of time steps in first run L.runs\[0\].ke # list of kinetic energy values in first run :pre Together with matplotlib plotting data out of LAMMPS becomes simple: import matplotlib.plot as plt steps = L.runs\[0\].step ke = L.runs\[0\].ke plt.plot(steps, ke) :pre Error handling with PyLammps :h2 Compiling the shared library with C++ exception support provides a better error handling experience. Without exceptions the LAMMPS code will terminate the current Python process with an error message. C++ exceptions allow capturing them on the C++ side and rethrowing them on the Python side. This way you can handle LAMMPS errors through the Python exception handling mechanism. IMPORTANT NOTE: Capturing a LAMMPS exception in Python can still mean that the current LAMMPS process is in an illegal state and must be terminated. It is advised to save your data and terminate the Python instance as quickly as possible. Using PyLammps in IPython notebooks and Jupyter :h2 If the LAMMPS Python package is installed for the same Python interpreter as IPython, you can use PyLammps directly inside of an IPython notebook inside of Jupyter. Jupyter is a powerful integrated development environment (IDE) for many dynamic languages like Python, Julia and others, which operates inside of any web browser. Besides auto-completion and syntax highlighting it allows you to create formatted documents using Markup, mathematical formulas, graphics and animations intermixed with executable Python code. It is a great format for tutorials and showcasing your latest research. To launch an instance of Jupyter simply run the following command inside your Python environment (this assumes you followed the Quick Start instructions): jupyter notebook :pre IPyLammps Examples :h2 Examples of IPython notebooks can be found in the python/examples/pylammps subdirectory. To open these notebooks launch {jupyter notebook} inside this -directory and navigate to one of them. If you compiled and installed +directory and navigate to one of them. If you compiled and installed a LAMMPS shared library with exceptions, PNG, JPEG and FFMPEG support you should be able to rerun all of these notebooks. Validating a dihedral potential :h3 This example showcases how an IPython Notebook can be used to compare a simple LAMMPS simulation of a harmonic dihedral potential to its analytical solution. Four atoms are placed in the simulation and the dihedral potential is applied on them using a datafile. Then one of the atoms is rotated along the central axis by setting its position from Python, which changes the dihedral angle. phi = \[d * math.pi / 180 for d in range(360)\] :pre pos = \[(1.0, math.cos(p), math.sin(p)) for p in phi\] :pre pe = \[\] for p in pos: L.atoms\[3\].position = p L.run(0) pe.append(L.eval("pe")) :pre By evaluating the potential energy for each position we can verify that trajectory with the analytical formula. To compare both solutions, we plot both trajectories over each other using matplotlib, which embeds the generated plot inside the IPython notebook. :c,image(JPG/pylammps_dihedral.jpg) Running a Monte Carlo relaxation :h3 This second example shows how to use PyLammps to create a 2D Monte Carlo Relaxation simulation, computing and plotting energy terms and even embedding video output. Initially, a 2D system is created in a state with minimal energy. :c,image(JPG/pylammps_mc_minimum.jpg) It is then disordered by moving each atom by a random delta. random.seed(27848) deltaperturb = 0.2 :pre for i in range(L.system.natoms): x, y = L.atoms\[i\].position dx = deltaperturb * random.uniform(-1, 1) dy = deltaperturb * random.uniform(-1, 1) L.atoms\[i\].position = (x+dx, y+dy) :pre L.run(0) :pre :c,image(JPG/pylammps_mc_disordered.jpg) Finally, the Monte Carlo algorithm is implemented in Python. It continuously moves random atoms by a random delta and only accepts certain moves. estart = L.eval("pe") elast = estart :pre naccept = 0 energies = \[estart\] :pre niterations = 3000 deltamove = 0.1 kT = 0.05 :pre natoms = L.system.natoms :pre for i in range(niterations): iatom = random.randrange(0, natoms) current_atom = L.atoms\[iatom\] :pre - + x0, y0 = current_atom.position :pre - + dx = deltamove * random.uniform(-1, 1) dy = deltamove * random.uniform(-1, 1) :pre - + current_atom.position = (x0+dx, y0+dy) :pre - + L.run(1, "pre no post no") :pre - + e = L.eval("pe") energies.append(e) :pre - + if e <= elast: naccept += 1 elast = e elif random.random() <= math.exp(natoms*(elast-e)/kT): naccept += 1 elast = e else: current_atom.position = (x0, y0) :pre The energies of each iteration are collected in a Python list and finally plotted using matplotlib. :c,image(JPG/pylammps_mc_energies_plot.jpg) The IPython notebook also shows how to use dump commands and embed video files inside of the IPython notebook. Using PyLammps and mpi4py (Experimental) :h2 PyLammps can be run in parallel using mpi4py. This python package can be installed using pip install mpi4py :pre The following is a short example which reads in an existing LAMMPS input file and executes it in parallel. You can find in.melt in the examples/melt folder. from mpi4py import MPI from lammps import PyLammps :pre L = PyLammps() L.file("in.melt") :pre if MPI.COMM_WORLD.rank == 0: print("Potential energy: ", L.eval("pe")) :pre MPI.Finalize() :pre To run this script (melt.py) in parallel using 4 MPI processes we invoke the following mpirun command: mpirun -np 4 python melt.py :pre IMPORTANT NOTE: Any command must be executed by all MPI processes. However, evaluations and querying the system state is only available on rank 0. Feedback and Contributing :h2 If you find this Python interface useful, please feel free to provide feedback and ideas on how to improve it to Richard Berger (richard.berger@temple.edu). We also want to encourage people to write tutorial style IPython notebooks showcasing LAMMPS usage -and maybe their latest research results. +and maybe their latest research results. diff --git a/examples/USER/misc/filter_corotate/in.bpti b/examples/USER/misc/filter_corotate/in.bpti index 6507a7870..2e4d8dda6 100644 --- a/examples/USER/misc/filter_corotate/in.bpti +++ b/examples/USER/misc/filter_corotate/in.bpti @@ -1,43 +1,43 @@ units real atom_style full bond_style harmonic angle_style charmm dihedral_style charmm improper_style harmonic pair_style lj/charmm/coul/long 8 10 pair_modify mix arithmetic kspace_style pppm 1e-4 read_data data.bpti special_bonds charmm neigh_modify delay 2 every 1 # ------------- MINIMIZE ---------- minimize 1e-4 1e-6 1000 10000 reset_timestep 0 # ------------- RUN --------------- thermo 100 thermo_style multi timestep 8 -run_style respa 3 2 8 bond 1 pair 2 kspace 3 +run_style respa 3 2 8 bond 1 dihedral 2 pair 2 kspace 3 velocity all create 200.0 12345678 dist uniform #dump dump1 all atom 100 4pti.dump fix 1 all nvt temp 200 300 25 fix cor all filter/corotate m 1.0 run 1000 unfix cor unfix 1 diff --git a/examples/USER/misc/filter_corotate/in.peptide b/examples/USER/misc/filter_corotate/in.peptide index 0a17f995b..e10dc09f0 100644 --- a/examples/USER/misc/filter_corotate/in.peptide +++ b/examples/USER/misc/filter_corotate/in.peptide @@ -1,32 +1,32 @@ # Solvated 5-mer peptide, run for 8ps in NVT units real atom_style full pair_style lj/charmm/coul/long 8.0 10.0 10.0 bond_style harmonic angle_style charmm dihedral_style charmm improper_style harmonic kspace_style pppm 0.0001 read_data data.peptide neighbor 2.0 bin neigh_modify delay 5 thermo 50 #dump dump1 all atom 100 peptide.dump timestep 8 -run_style respa 3 2 8 bond 1 pair 2 kspace 3 +run_style respa 3 2 8 bond 1 dihedral 2 pair 2 kspace 3 fix 1 all nvt temp 250.0 250.0 100.0 tchain 1 fix cor all filter/corotate m 1.0 run 1000 unfix cor unfix 1 diff --git a/examples/USER/misc/filter_corotate/log.10Mar2017.bpti.g++.1 b/examples/USER/misc/filter_corotate/log.10Mar2017.bpti.g++.1 deleted file mode 100644 index 5253b47b2..000000000 --- a/examples/USER/misc/filter_corotate/log.10Mar2017.bpti.g++.1 +++ /dev/null @@ -1,240 +0,0 @@ -LAMMPS (10 Mar 2017) - using 1 OpenMP thread(s) per MPI task - -units real - -atom_style full -bond_style harmonic -angle_style charmm -dihedral_style charmm -improper_style harmonic - -pair_style lj/charmm/coul/long 8 10 -pair_modify mix arithmetic -kspace_style pppm 1e-4 - -read_data data.bpti - orthogonal box = (-10 -10 -30) to (50 50 30) - 1 by 1 by 1 MPI processor grid - reading atoms ... - 892 atoms - scanning bonds ... - 4 = max bonds/atom - scanning angles ... - 6 = max angles/atom - scanning dihedrals ... - 18 = max dihedrals/atom - scanning impropers ... - 2 = max impropers/atom - reading bonds ... - 906 bonds - reading angles ... - 1626 angles - reading dihedrals ... - 2501 dihedrals - reading impropers ... - 137 impropers - 4 = max # of 1-2 neighbors - 9 = max # of 1-3 neighbors - 19 = max # of 1-4 neighbors - 21 = max # of special neighbors - -special_bonds charmm -neigh_modify delay 2 every 1 - - -# ------------- MINIMIZE ---------- - -minimize 1e-4 1e-6 1000 10000 -WARNING: Resetting reneighboring criteria during minimization (../min.cpp:168) -PPPM initialization ... -WARNING: System is not charge neutral, net charge = 6 (../kspace.cpp:302) -WARNING: Using 12-bit tables for long-range coulomb (../kspace.cpp:321) - G vector (1/distance) = 0.203272 - grid = 16 16 16 - stencil order = 5 - estimated absolute RMS force accuracy = 0.0316399 - estimated relative force accuracy = 9.52826e-05 - using double precision FFTs - 3d grid and FFT values/proc = 9261 4096 -Neighbor list info ... - update every 1 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 12 - ghost atom cutoff = 12 - binsize = 6, bins = 10 10 10 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair lj/charmm/coul/long, perpetual - attributes: half, newton on - pair build: half/bin/newton - stencil: half/bin/3d/newton - bin: standard -Per MPI rank memory usage (min/avg/max) = 17.8596/1/0 Mbytes -Step Temp E_pair E_mol TotEng Press - 0 0 -3075.6498 943.91164 -2131.7381 -380.67776 - 241 0 -4503.313 749.58662 -3753.7264 -29.045104 -Loop time of 3.35722 on 1 procs for 241 steps with 892 atoms - -99.7% CPU use with 1 MPI tasks x 1 OpenMP threads - -Minimization stats: - Stopping criterion = energy tolerance - Energy initial, next-to-last, final = - -2131.73812515 -3753.43984087 -3753.72636847 - Force two-norm initial, final = 1086.21 26.3688 - Force max component initial, final = 310.811 3.92748 - Final line search alpha, max atom move = 0.00596649 0.0234333 - Iterations, force evaluations = 241 463 - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 2.5003 | 2.5003 | 2.5003 | 0.0 | 74.48 -Bond | 0.24287 | 0.24287 | 0.24287 | 0.0 | 7.23 -Kspace | 0.53428 | 0.53428 | 0.53428 | 0.0 | 15.91 -Neigh | 0.069765 | 0.069765 | 0.069765 | 0.0 | 2.08 -Comm | 0.00065374 | 0.00065374 | 0.00065374 | 0.0 | 0.02 -Output | 0 | 0 | 0 | 0.0 | 0.00 -Modify | 0 | 0 | 0 | 0.0 | 0.00 -Other | | 0.009358 | | | 0.28 - -Nlocal: 892 ave 892 max 892 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 31 ave 31 max 31 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 148891 ave 148891 max 148891 min -Histogram: 1 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 148891 -Ave neighs/atom = 166.918 -Ave special neighs/atom = 10.9395 -Neighbor list builds = 15 -Dangerous builds = 0 -reset_timestep 0 - -# ------------- RUN --------------- - -thermo 100 -thermo_style multi -timestep 8 - -run_style respa 3 2 8 bond 1 pair 2 kspace 3 -Respa levels: - 1 = bond angle dihedral improper - 2 = pair - 3 = kspace - -velocity all create 200.0 12345678 dist uniform -#dump dump1 all atom 100 4pti.dump - -fix 1 all nvt temp 200 300 25 -fix cor all filter/corotate m 1.0 - 163 = # of size 2 clusters - 0 = # of size 3 clusters - 25 = # of size 4 clusters - 0 = # of size 5 clusters - 100 = # of frozen angles - -run 1000 -PPPM initialization ... -WARNING: Using 12-bit tables for long-range coulomb (../kspace.cpp:321) - G vector (1/distance) = 0.203272 - grid = 16 16 16 - stencil order = 5 - estimated absolute RMS force accuracy = 0.0316399 - estimated relative force accuracy = 9.52826e-05 - using double precision FFTs - 3d grid and FFT values/proc = 9261 4096 -Per MPI rank memory usage (min/avg/max) = 19.5425/1/0 Mbytes ----------------- Step 0 ----- CPU = 0.0000 (sec) ---------------- -TotEng = -3220.3378 KinEng = 531.1804 Temp = 200.0000 -PotEng = -3751.5181 E_bond = 42.2810 E_angle = 345.2592 -E_dihed = 337.8361 E_impro = 24.2103 E_vdwl = -288.5339 -E_coul = -886.3622 E_long = -3326.2088 Press = 83.2283 ----------------- Step 100 ----- CPU = 3.9414 (sec) ---------------- -TotEng = -2718.8970 KinEng = 538.6206 Temp = 202.8014 -PotEng = -3257.5176 E_bond = 203.3367 E_angle = 566.5317 -E_dihed = 397.6202 E_impro = 34.6623 E_vdwl = -248.7451 -E_coul = -874.5122 E_long = -3336.4111 Press = 135.8662 ----------------- Step 200 ----- CPU = 7.9028 (sec) ---------------- -TotEng = -2660.1406 KinEng = 626.3319 Temp = 235.8265 -PotEng = -3286.4725 E_bond = 209.5147 E_angle = 591.7773 -E_dihed = 388.9591 E_impro = 29.4992 E_vdwl = -243.5808 -E_coul = -923.5115 E_long = -3339.1306 Press = 88.9000 ----------------- Step 300 ----- CPU = 11.8246 (sec) ---------------- -TotEng = -2673.8090 KinEng = 616.7924 Temp = 232.2346 -PotEng = -3290.6014 E_bond = 202.8254 E_angle = 568.6860 -E_dihed = 378.4182 E_impro = 38.2399 E_vdwl = -221.3236 -E_coul = -915.3004 E_long = -3342.1468 Press = 78.8527 ----------------- Step 400 ----- CPU = 15.7990 (sec) ---------------- -TotEng = -2614.9416 KinEng = 649.3474 Temp = 244.4922 -PotEng = -3264.2890 E_bond = 211.6116 E_angle = 617.2026 -E_dihed = 399.8744 E_impro = 40.2678 E_vdwl = -211.7790 -E_coul = -978.1624 E_long = -3343.3041 Press = -4.1958 ----------------- Step 500 ----- CPU = 19.8146 (sec) ---------------- -TotEng = -2588.6772 KinEng = 660.1424 Temp = 248.5568 -PotEng = -3248.8196 E_bond = 218.4786 E_angle = 620.8605 -E_dihed = 390.3220 E_impro = 41.6794 E_vdwl = -226.3657 -E_coul = -953.1676 E_long = -3340.6269 Press = 99.3200 ----------------- Step 600 ----- CPU = 23.8587 (sec) ---------------- -TotEng = -2550.4618 KinEng = 693.3384 Temp = 261.0557 -PotEng = -3243.8002 E_bond = 232.3563 E_angle = 606.2922 -E_dihed = 396.2469 E_impro = 37.1980 E_vdwl = -235.8425 -E_coul = -937.1208 E_long = -3342.9303 Press = -21.7737 ----------------- Step 700 ----- CPU = 27.8381 (sec) ---------------- -TotEng = -2554.4355 KinEng = 692.8951 Temp = 260.8888 -PotEng = -3247.3306 E_bond = 216.3395 E_angle = 637.7785 -E_dihed = 391.5940 E_impro = 43.1426 E_vdwl = -187.6159 -E_coul = -1008.1694 E_long = -3340.3998 Press = 75.1484 ----------------- Step 800 ----- CPU = 31.8039 (sec) ---------------- -TotEng = -2508.3551 KinEng = 699.0766 Temp = 263.2163 -PotEng = -3207.4317 E_bond = 241.9936 E_angle = 641.3631 -E_dihed = 386.2198 E_impro = 43.7793 E_vdwl = -217.7523 -E_coul = -964.6070 E_long = -3338.4282 Press = -127.7337 ----------------- Step 900 ----- CPU = 35.7700 (sec) ---------------- -TotEng = -2452.7644 KinEng = 762.1842 Temp = 286.9776 -PotEng = -3214.9485 E_bond = 243.9191 E_angle = 649.8664 -E_dihed = 382.4351 E_impro = 39.0029 E_vdwl = -221.3389 -E_coul = -970.8965 E_long = -3337.9366 Press = 122.7720 ----------------- Step 1000 ----- CPU = 39.7695 (sec) ---------------- -TotEng = -2386.6805 KinEng = 799.0253 Temp = 300.8490 -PotEng = -3185.7058 E_bond = 265.3649 E_angle = 661.7543 -E_dihed = 374.6843 E_impro = 38.6877 E_vdwl = -229.2030 -E_coul = -960.7041 E_long = -3336.2899 Press = -17.9910 -Loop time of 39.7695 on 1 procs for 1000 steps with 892 atoms - -Performance: 17.380 ns/day, 1.381 hours/ns, 25.145 timesteps/s -99.6% CPU use with 1 MPI tasks x 1 OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 29.169 | 29.169 | 29.169 | 0.0 | 73.34 -Bond | 7.6249 | 7.6249 | 7.6249 | 0.0 | 19.17 -Kspace | 1.1525 | 1.1525 | 1.1525 | 0.0 | 2.90 -Neigh | 0.87606 | 0.87606 | 0.87606 | 0.0 | 2.20 -Comm | 0.01563 | 0.01563 | 0.01563 | 0.0 | 0.04 -Output | 0.00048423 | 0.00048423 | 0.00048423 | 0.0 | 0.00 -Modify | 0.80446 | 0.80446 | 0.80446 | 0.0 | 2.02 -Other | | 0.1266 | | | 0.32 - -Nlocal: 892 ave 892 max 892 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 27 ave 27 max 27 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 146206 ave 146206 max 146206 min -Histogram: 1 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 146206 -Ave neighs/atom = 163.908 -Ave special neighs/atom = 10.9395 -Neighbor list builds = 186 -Dangerous builds = 0 - -unfix cor -unfix 1 - - -Please see the log.cite file for references relevant to this simulation - -Total wall time: 0:00:43 diff --git a/examples/USER/misc/filter_corotate/log.10Mar2017.bpti.g++.4 b/examples/USER/misc/filter_corotate/log.10Mar2017.bpti.g++.4 deleted file mode 100644 index 4300c1caf..000000000 --- a/examples/USER/misc/filter_corotate/log.10Mar2017.bpti.g++.4 +++ /dev/null @@ -1,240 +0,0 @@ -LAMMPS (10 Mar 2017) - using 1 OpenMP thread(s) per MPI task - -units real - -atom_style full -bond_style harmonic -angle_style charmm -dihedral_style charmm -improper_style harmonic - -pair_style lj/charmm/coul/long 8 10 -pair_modify mix arithmetic -kspace_style pppm 1e-4 - -read_data data.bpti - orthogonal box = (-10 -10 -30) to (50 50 30) - 1 by 2 by 2 MPI processor grid - reading atoms ... - 892 atoms - scanning bonds ... - 4 = max bonds/atom - scanning angles ... - 6 = max angles/atom - scanning dihedrals ... - 18 = max dihedrals/atom - scanning impropers ... - 2 = max impropers/atom - reading bonds ... - 906 bonds - reading angles ... - 1626 angles - reading dihedrals ... - 2501 dihedrals - reading impropers ... - 137 impropers - 4 = max # of 1-2 neighbors - 9 = max # of 1-3 neighbors - 19 = max # of 1-4 neighbors - 21 = max # of special neighbors - -special_bonds charmm -neigh_modify delay 2 every 1 - - -# ------------- MINIMIZE ---------- - -minimize 1e-4 1e-6 1000 10000 -WARNING: Resetting reneighboring criteria during minimization (../min.cpp:168) -PPPM initialization ... -WARNING: System is not charge neutral, net charge = 6 (../kspace.cpp:302) -WARNING: Using 12-bit tables for long-range coulomb (../kspace.cpp:321) - G vector (1/distance) = 0.203272 - grid = 16 16 16 - stencil order = 5 - estimated absolute RMS force accuracy = 0.0316399 - estimated relative force accuracy = 9.52826e-05 - using double precision FFTs - 3d grid and FFT values/proc = 3549 1024 -Neighbor list info ... - update every 1 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 12 - ghost atom cutoff = 12 - binsize = 6, bins = 10 10 10 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair lj/charmm/coul/long, perpetual - attributes: half, newton on - pair build: half/bin/newton - stencil: half/bin/3d/newton - bin: standard -Per MPI rank memory usage (min/avg/max) = 16.9693/0.981879/0 Mbytes -Step Temp E_pair E_mol TotEng Press - 0 0 -3075.6498 943.91164 -2131.7381 -380.67776 - 241 0 -4503.3131 749.58666 -3753.7264 -29.045153 -Loop time of 1.26594 on 4 procs for 241 steps with 892 atoms - -99.0% CPU use with 4 MPI tasks x 1 OpenMP threads - -Minimization stats: - Stopping criterion = energy tolerance - Energy initial, next-to-last, final = - -2131.73812515 -3753.43983927 -3753.72640137 - Force two-norm initial, final = 1086.21 26.3688 - Force max component initial, final = 310.811 3.92751 - Final line search alpha, max atom move = 0.00596649 0.0234334 - Iterations, force evaluations = 241 463 - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 0.34267 | 0.63792 | 0.90268 | 25.2 | 50.39 -Bond | 0.025776 | 0.063318 | 0.095631 | 10.8 | 5.00 -Kspace | 0.21904 | 0.51601 | 0.84895 | 31.3 | 40.76 -Neigh | 0.023185 | 0.023363 | 0.023538 | 0.1 | 1.85 -Comm | 0.012025 | 0.014189 | 0.016335 | 1.4 | 1.12 -Output | 0 | 0 | 0 | 0.0 | 0.00 -Modify | 0 | 0 | 0 | 0.0 | 0.00 -Other | | 0.01114 | | | 0.88 - -Nlocal: 223 ave 323 max 89 min -Histogram: 1 0 0 0 1 0 0 0 1 1 -Nghost: 613 ave 675 max 557 min -Histogram: 1 0 0 1 0 1 0 0 0 1 -Neighs: 37222.8 ave 50005 max 20830 min -Histogram: 1 0 0 0 1 0 0 1 0 1 - -Total # of neighbors = 148891 -Ave neighs/atom = 166.918 -Ave special neighs/atom = 10.9395 -Neighbor list builds = 15 -Dangerous builds = 0 -reset_timestep 0 - -# ------------- RUN --------------- - -thermo 100 -thermo_style multi -timestep 8 - -run_style respa 3 2 8 bond 1 pair 2 kspace 3 -Respa levels: - 1 = bond angle dihedral improper - 2 = pair - 3 = kspace - -velocity all create 200.0 12345678 dist uniform -#dump dump1 all atom 100 4pti.dump - -fix 1 all nvt temp 200 300 25 -fix cor all filter/corotate m 1.0 - 163 = # of size 2 clusters - 0 = # of size 3 clusters - 25 = # of size 4 clusters - 0 = # of size 5 clusters - 100 = # of frozen angles - -run 1000 -PPPM initialization ... -WARNING: Using 12-bit tables for long-range coulomb (../kspace.cpp:321) - G vector (1/distance) = 0.203272 - grid = 16 16 16 - stencil order = 5 - estimated absolute RMS force accuracy = 0.0316399 - estimated relative force accuracy = 9.52826e-05 - using double precision FFTs - 3d grid and FFT values/proc = 3549 1024 -Per MPI rank memory usage (min/avg/max) = 17.142/0.97212/0 Mbytes ----------------- Step 0 ----- CPU = 0.0000 (sec) ---------------- -TotEng = -3220.3378 KinEng = 531.1804 Temp = 200.0000 -PotEng = -3751.5182 E_bond = 42.2810 E_angle = 345.2592 -E_dihed = 337.8361 E_impro = 24.2103 E_vdwl = -288.5339 -E_coul = -886.3622 E_long = -3326.2088 Press = 83.2282 ----------------- Step 100 ----- CPU = 1.5457 (sec) ---------------- -TotEng = -2718.9184 KinEng = 538.6205 Temp = 202.8014 -PotEng = -3257.5389 E_bond = 203.3365 E_angle = 566.5311 -E_dihed = 397.6202 E_impro = 34.6621 E_vdwl = -248.7451 -E_coul = -874.5326 E_long = -3336.4111 Press = 135.8435 ----------------- Step 200 ----- CPU = 3.0720 (sec) ---------------- -TotEng = -2660.1146 KinEng = 626.3474 Temp = 235.8323 -PotEng = -3286.4620 E_bond = 209.5168 E_angle = 591.7735 -E_dihed = 388.9615 E_impro = 29.5000 E_vdwl = -243.5840 -E_coul = -923.4998 E_long = -3339.1299 Press = 88.8857 ----------------- Step 300 ----- CPU = 4.5597 (sec) ---------------- -TotEng = -2669.7442 KinEng = 619.3625 Temp = 233.2023 -PotEng = -3289.1067 E_bond = 203.4405 E_angle = 569.5281 -E_dihed = 378.3314 E_impro = 38.2880 E_vdwl = -221.1904 -E_coul = -915.3396 E_long = -3342.1646 Press = 79.3780 ----------------- Step 400 ----- CPU = 5.9808 (sec) ---------------- -TotEng = -2618.9975 KinEng = 644.6145 Temp = 242.7102 -PotEng = -3263.6119 E_bond = 209.5864 E_angle = 618.8954 -E_dihed = 401.3798 E_impro = 39.9064 E_vdwl = -212.1271 -E_coul = -977.1589 E_long = -3344.0940 Press = -7.8938 ----------------- Step 500 ----- CPU = 7.4159 (sec) ---------------- -TotEng = -2579.7486 KinEng = 666.4643 Temp = 250.9371 -PotEng = -3246.2129 E_bond = 219.2549 E_angle = 620.3474 -E_dihed = 388.4395 E_impro = 41.4499 E_vdwl = -225.9686 -E_coul = -949.3689 E_long = -3340.3672 Press = 113.2543 ----------------- Step 600 ----- CPU = 8.9252 (sec) ---------------- -TotEng = -2535.8235 KinEng = 708.5919 Temp = 266.7990 -PotEng = -3244.4154 E_bond = 243.9451 E_angle = 606.0866 -E_dihed = 400.0562 E_impro = 33.9708 E_vdwl = -223.1319 -E_coul = -964.9940 E_long = -3340.3482 Press = -102.4475 ----------------- Step 700 ----- CPU = 10.4022 (sec) ---------------- -TotEng = -2552.6681 KinEng = 702.3080 Temp = 264.4330 -PotEng = -3254.9761 E_bond = 250.8834 E_angle = 639.0977 -E_dihed = 386.4014 E_impro = 42.3004 E_vdwl = -224.4816 -E_coul = -1011.8551 E_long = -3337.3222 Press = 10.6424 ----------------- Step 800 ----- CPU = 11.8699 (sec) ---------------- -TotEng = -2423.5415 KinEng = 772.1254 Temp = 290.7206 -PotEng = -3195.6670 E_bond = 238.5831 E_angle = 640.9180 -E_dihed = 377.7994 E_impro = 40.3135 E_vdwl = -216.5705 -E_coul = -935.1087 E_long = -3341.6019 Press = -38.2479 ----------------- Step 900 ----- CPU = 13.3548 (sec) ---------------- -TotEng = -2394.4779 KinEng = 766.6895 Temp = 288.6739 -PotEng = -3161.1673 E_bond = 284.8428 E_angle = 671.0959 -E_dihed = 380.3406 E_impro = 51.2975 E_vdwl = -219.5211 -E_coul = -990.6305 E_long = -3338.5925 Press = -15.2279 ----------------- Step 1000 ----- CPU = 14.7908 (sec) ---------------- -TotEng = -2340.1471 KinEng = 799.0198 Temp = 300.8469 -PotEng = -3139.1669 E_bond = 271.0389 E_angle = 683.8278 -E_dihed = 407.0795 E_impro = 39.6209 E_vdwl = -230.5355 -E_coul = -974.2981 E_long = -3335.9003 Press = -94.3420 -Loop time of 14.7909 on 4 procs for 1000 steps with 892 atoms - -Performance: 46.732 ns/day, 0.514 hours/ns, 67.609 timesteps/s -99.1% CPU use with 4 MPI tasks x 1 OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 4.4184 | 7.5543 | 10.133 | 74.2 | 51.07 -Bond | 0.94027 | 1.9781 | 2.7492 | 54.4 | 13.37 -Kspace | 0.45487 | 0.45887 | 0.46343 | 0.4 | 3.10 -Neigh | 0.28145 | 0.28339 | 0.28539 | 0.3 | 1.92 -Comm | 0.7515 | 4.1484 | 8.3861 | 135.5 | 28.05 -Output | 0.00049973 | 0.00055474 | 0.00066924 | 0.0 | 0.00 -Modify | 0.26165 | 0.31142 | 0.35023 | 6.7 | 2.11 -Other | | 0.05572 | | | 0.38 - -Nlocal: 223 ave 313 max 122 min -Histogram: 1 0 0 1 0 0 0 1 0 1 -Nghost: 584.5 ave 605 max 553 min -Histogram: 1 0 0 0 0 1 0 0 0 2 -Neighs: 35448 ave 42093 max 25175 min -Histogram: 1 0 0 0 0 0 1 1 0 1 - -Total # of neighbors = 141792 -Ave neighs/atom = 158.96 -Ave special neighs/atom = 10.9395 -Neighbor list builds = 186 -Dangerous builds = 0 - -unfix cor -unfix 1 - - -Please see the log.cite file for references relevant to this simulation - -Total wall time: 0:00:16 diff --git a/examples/USER/misc/filter_corotate/log.10Mar2017.peptide.g++.1 b/examples/USER/misc/filter_corotate/log.10Mar2017.peptide.g++.1 deleted file mode 100644 index 23dd4c8a8..000000000 --- a/examples/USER/misc/filter_corotate/log.10Mar2017.peptide.g++.1 +++ /dev/null @@ -1,146 +0,0 @@ -LAMMPS (10 Mar 2017) - using 1 OpenMP thread(s) per MPI task -# Solvated 5-mer peptide, run for 8ps in NVT - -units real -atom_style full - -pair_style lj/charmm/coul/long 8.0 10.0 10.0 -bond_style harmonic -angle_style charmm -dihedral_style charmm -improper_style harmonic -kspace_style pppm 0.0001 - -read_data data.peptide - orthogonal box = (36.8402 41.0137 29.7681) to (64.2116 68.3851 57.1395) - 1 by 1 by 1 MPI processor grid - reading atoms ... - 2004 atoms - reading velocities ... - 2004 velocities - scanning bonds ... - 3 = max bonds/atom - scanning angles ... - 6 = max angles/atom - scanning dihedrals ... - 14 = max dihedrals/atom - scanning impropers ... - 1 = max impropers/atom - reading bonds ... - 1365 bonds - reading angles ... - 786 angles - reading dihedrals ... - 207 dihedrals - reading impropers ... - 12 impropers - 4 = max # of 1-2 neighbors - 7 = max # of 1-3 neighbors - 14 = max # of 1-4 neighbors - 18 = max # of special neighbors - -neighbor 2.0 bin -neigh_modify delay 5 - -thermo 50 -#dump dump1 all atom 100 peptide.dump - -timestep 8 - -run_style respa 3 2 8 bond 1 pair 2 kspace 3 -Respa levels: - 1 = bond angle dihedral improper - 2 = pair - 3 = kspace - -fix 1 all nvt temp 250.0 250.0 100.0 tchain 1 -fix cor all filter/corotate m 1.0 - 19 = # of size 2 clusters - 0 = # of size 3 clusters - 3 = # of size 4 clusters - 0 = # of size 5 clusters - 646 = # of frozen angles -run 1000 -PPPM initialization ... -WARNING: Using 12-bit tables for long-range coulomb (../kspace.cpp:321) - G vector (1/distance) = 0.268725 - grid = 15 15 15 - stencil order = 5 - estimated absolute RMS force accuracy = 0.0228209 - estimated relative force accuracy = 6.87243e-05 - using double precision FFTs - 3d grid and FFT values/proc = 10648 3375 -Neighbor list info ... - update every 1 steps, delay 5 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 12 - ghost atom cutoff = 12 - binsize = 6, bins = 5 5 5 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair lj/charmm/coul/long, perpetual - attributes: half, newton on - pair build: half/bin/newton - stencil: half/bin/3d/newton - bin: standard -Per MPI rank memory usage (min/avg/max) = 22.6706/1/0 Mbytes -Step Temp E_pair E_mol TotEng Press - 0 190.0857 -6785.6785 70.391457 -5580.3684 19434.821 - 50 239.46028 -7546.5667 1092.8874 -5023.9668 -24643.891 - 100 242.81799 -7125.5527 416.0788 -5259.7139 15525.465 - 150 235.97108 -7531.9334 932.35464 -5190.6987 -14838.489 - 200 252.06415 -7195.6011 568.02993 -5122.6064 8841.332 - 250 249.99431 -7586.5092 881.83491 -5212.0676 -9330.345 - 300 240.3382 -7333.0933 633.29951 -5264.8395 5137.9757 - 350 255.34529 -7568.2413 856.46371 -5187.2226 -6206.063 - 400 242.99276 -7419.9031 713.23943 -5255.8602 2447.0091 - 450 251.10653 -7622.061 844.20584 -5278.6079 -4906.6559 - 500 255.59314 -7439.253 710.84907 -5202.3691 1571.0032 - 550 253.2025 -7660.5101 823.05373 -5325.695 -4551.399 - 600 249.05313 -7509.6729 741.48104 -5281.2046 992.87 - 650 251.75984 -7593.6589 847.08244 -5243.4286 -3510.1176 - 700 249.25027 -7601.9112 794.0912 -5319.6557 305.76021 - 750 255.415 -7602.2674 822.98524 -5254.3109 -2333.421 - 800 241.99621 -7643.8878 796.53352 -5402.5008 -298.66565 - 850 253.6428 -7598.3764 816.45457 -5267.5316 -1905.3478 - 900 247.20231 -7690.2806 789.75999 -5424.5838 -1331.7228 - 950 255.92583 -7634.7505 831.18272 -5275.5466 -2186.5117 - 1000 253.2126 -7647.9526 823.93602 -5312.195 -1189.9659 -Loop time of 150.664 on 1 procs for 1000 steps with 2004 atoms - -Performance: 4.588 ns/day, 5.231 hours/ns, 6.637 timesteps/s -99.7% CPU use with 1 MPI tasks x 1 OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 135.81 | 135.81 | 135.81 | 0.0 | 90.14 -Bond | 2.5889 | 2.5889 | 2.5889 | 0.0 | 1.72 -Kspace | 2.0379 | 2.0379 | 2.0379 | 0.0 | 1.35 -Neigh | 5.893 | 5.893 | 5.893 | 0.0 | 3.91 -Comm | 1.6998 | 1.6998 | 1.6998 | 0.0 | 1.13 -Output | 0.00077915 | 0.00077915 | 0.00077915 | 0.0 | 0.00 -Modify | 2 | 2 | 2 | 0.0 | 1.33 -Other | | 0.6352 | | | 0.42 - -Nlocal: 2004 ave 2004 max 2004 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 11197 ave 11197 max 11197 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 707779 ave 707779 max 707779 min -Histogram: 1 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 707779 -Ave neighs/atom = 353.183 -Ave special neighs/atom = 2.34032 -Neighbor list builds = 200 -Dangerous builds = 200 -unfix cor -unfix 1 - - - - -Please see the log.cite file for references relevant to this simulation - -Total wall time: 0:02:30 diff --git a/examples/USER/misc/filter_corotate/log.10Mar2017.peptide.g++.4 b/examples/USER/misc/filter_corotate/log.10Mar2017.peptide.g++.4 deleted file mode 100644 index 2cdd645fe..000000000 --- a/examples/USER/misc/filter_corotate/log.10Mar2017.peptide.g++.4 +++ /dev/null @@ -1,146 +0,0 @@ -LAMMPS (10 Mar 2017) - using 1 OpenMP thread(s) per MPI task -# Solvated 5-mer peptide, run for 8ps in NVT - -units real -atom_style full - -pair_style lj/charmm/coul/long 8.0 10.0 10.0 -bond_style harmonic -angle_style charmm -dihedral_style charmm -improper_style harmonic -kspace_style pppm 0.0001 - -read_data data.peptide - orthogonal box = (36.8402 41.0137 29.7681) to (64.2116 68.3851 57.1395) - 1 by 2 by 2 MPI processor grid - reading atoms ... - 2004 atoms - reading velocities ... - 2004 velocities - scanning bonds ... - 3 = max bonds/atom - scanning angles ... - 6 = max angles/atom - scanning dihedrals ... - 14 = max dihedrals/atom - scanning impropers ... - 1 = max impropers/atom - reading bonds ... - 1365 bonds - reading angles ... - 786 angles - reading dihedrals ... - 207 dihedrals - reading impropers ... - 12 impropers - 4 = max # of 1-2 neighbors - 7 = max # of 1-3 neighbors - 14 = max # of 1-4 neighbors - 18 = max # of special neighbors - -neighbor 2.0 bin -neigh_modify delay 5 - -thermo 50 -#dump dump1 all atom 100 peptide.dump - -timestep 8 - -run_style respa 3 2 8 bond 1 pair 2 kspace 3 -Respa levels: - 1 = bond angle dihedral improper - 2 = pair - 3 = kspace - -fix 1 all nvt temp 250.0 250.0 100.0 tchain 1 -fix cor all filter/corotate m 1.0 - 19 = # of size 2 clusters - 0 = # of size 3 clusters - 3 = # of size 4 clusters - 0 = # of size 5 clusters - 646 = # of frozen angles -run 1000 -PPPM initialization ... -WARNING: Using 12-bit tables for long-range coulomb (../kspace.cpp:321) - G vector (1/distance) = 0.268725 - grid = 15 15 15 - stencil order = 5 - estimated absolute RMS force accuracy = 0.0228209 - estimated relative force accuracy = 6.87243e-05 - using double precision FFTs - 3d grid and FFT values/proc = 4312 960 -Neighbor list info ... - update every 1 steps, delay 5 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 12 - ghost atom cutoff = 12 - binsize = 6, bins = 5 5 5 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair lj/charmm/coul/long, perpetual - attributes: half, newton on - pair build: half/bin/newton - stencil: half/bin/3d/newton - bin: standard -Per MPI rank memory usage (min/avg/max) = 16.8394/0.98826/0 Mbytes -Step Temp E_pair E_mol TotEng Press - 0 190.0857 -6785.6785 70.391457 -5580.3684 19434.821 - 50 239.46028 -7546.5668 1092.8874 -5023.9668 -24643.891 - 100 242.81819 -7125.5629 416.08082 -5259.7209 15525.244 - 150 235.94928 -7531.9186 932.50658 -5190.6621 -14842.431 - 200 255.85551 -7254.4065 568.8803 -5157.9249 8936.8651 - 250 247.8705 -7607.4583 858.06087 -5269.4711 -9926.0442 - 300 257.64176 -7267.424 618.5573 -5110.6004 5173.3307 - 350 251.65439 -7572.3806 821.15745 -5248.7049 -7092.327 - 400 256.87927 -7414.2145 655.33178 -5225.169 4119.4095 - 450 257.12393 -7576.5541 853.39773 -5187.9819 -5224.8823 - 500 242.42371 -7524.705 705.75357 -5371.5455 2111.3878 - 550 248.97188 -7541.076 792.86994 -5261.7038 -2278.4185 - 600 249.81862 -7592.0499 767.17722 -5333.3149 -1149.4759 - 650 253.31349 -7578.2665 813.75975 -5252.0827 -2915.5706 - 700 256.61152 -7588.1475 761.03356 -5294.9988 -747.88089 - 750 248.3606 -7660.457 837.71615 -5339.8883 -3072.8311 - 800 253.81464 -7638.6089 782.4229 -5340.7698 -1025.909 - 850 245.69185 -7660.9036 795.66792 -5398.3172 -2717.5851 - 900 249.13156 -7589.4769 806.43464 -5295.5867 -761.63361 - 950 251.11482 -7691.4981 869.34937 -5322.852 -3282.3031 - 1000 241.9195 -7630.9899 828.59107 -5358.0033 -95.962685 -Loop time of 45.5507 on 4 procs for 1000 steps with 2004 atoms - -Performance: 15.174 ns/day, 1.582 hours/ns, 21.954 timesteps/s -99.4% CPU use with 4 MPI tasks x 1 OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 35.545 | 36.674 | 38.004 | 15.8 | 80.51 -Bond | 0.51302 | 0.67796 | 0.86345 | 18.6 | 1.49 -Kspace | 0.66031 | 0.68459 | 0.70506 | 2.1 | 1.50 -Neigh | 1.5605 | 1.5627 | 1.5649 | 0.1 | 3.43 -Comm | 3.4611 | 4.9841 | 6.294 | 47.2 | 10.94 -Output | 0.00079799 | 0.00086641 | 0.0010369 | 0.0 | 0.00 -Modify | 0.67341 | 0.69059 | 0.71186 | 1.7 | 1.52 -Other | | 0.2762 | | | 0.61 - -Nlocal: 501 ave 523 max 473 min -Histogram: 1 0 0 0 0 0 2 0 0 1 -Nghost: 6643.25 ave 6708 max 6566 min -Histogram: 1 1 0 0 0 0 0 0 0 2 -Neighs: 176977 ave 185765 max 164931 min -Histogram: 1 0 0 0 1 0 0 0 1 1 - -Total # of neighbors = 707908 -Ave neighs/atom = 353.248 -Ave special neighs/atom = 2.34032 -Neighbor list builds = 200 -Dangerous builds = 200 -unfix cor -unfix 1 - - - - -Please see the log.cite file for references relevant to this simulation - -Total wall time: 0:00:45 diff --git a/examples/USER/misc/filter_corotate/log.22Jun2017.bpti.g++.1 b/examples/USER/misc/filter_corotate/log.22Jun2017.bpti.g++.1 new file mode 100644 index 000000000..1e708a9d3 --- /dev/null +++ b/examples/USER/misc/filter_corotate/log.22Jun2017.bpti.g++.1 @@ -0,0 +1,241 @@ +LAMMPS (20 Jun 2017) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (../comm.cpp:90) + using 1 OpenMP thread(s) per MPI task + +units real + +atom_style full +bond_style harmonic +angle_style charmm +dihedral_style charmm +improper_style harmonic + +pair_style lj/charmm/coul/long 8 10 +pair_modify mix arithmetic +kspace_style pppm 1e-4 + +read_data data.bpti + orthogonal box = (-10 -10 -30) to (50 50 30) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 892 atoms + scanning bonds ... + 4 = max bonds/atom + scanning angles ... + 6 = max angles/atom + scanning dihedrals ... + 18 = max dihedrals/atom + scanning impropers ... + 2 = max impropers/atom + reading bonds ... + 906 bonds + reading angles ... + 1626 angles + reading dihedrals ... + 2501 dihedrals + reading impropers ... + 137 impropers + 4 = max # of 1-2 neighbors + 9 = max # of 1-3 neighbors + 19 = max # of 1-4 neighbors + 21 = max # of special neighbors + +special_bonds charmm +neigh_modify delay 2 every 1 + + +# ------------- MINIMIZE ---------- + +minimize 1e-4 1e-6 1000 10000 +WARNING: Resetting reneighboring criteria during minimization (../min.cpp:168) +PPPM initialization ... +WARNING: System is not charge neutral, net charge = 6 (../kspace.cpp:302) +WARNING: Using 12-bit tables for long-range coulomb (../kspace.cpp:321) + G vector (1/distance) = 0.203272 + grid = 16 16 16 + stencil order = 5 + estimated absolute RMS force accuracy = 0.0316399 + estimated relative force accuracy = 9.52826e-05 + using double precision FFTs + 3d grid and FFT values/proc = 9261 4096 +Neighbor list info ... + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 12 + ghost atom cutoff = 12 + binsize = 6, bins = 10 10 10 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/charmm/coul/long, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/3d/newton + bin: standard +Per MPI rank memory allocation (min/avg/max) = 17.86 | 17.86 | 17.86 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 0 -3075.6498 943.91164 -2131.7381 -380.67776 + 241 0 -4503.313 749.58662 -3753.7264 -29.045104 +Loop time of 7.63279 on 1 procs for 241 steps with 892 atoms + +32.0% CPU use with 1 MPI tasks x 1 OpenMP threads + +Minimization stats: + Stopping criterion = energy tolerance + Energy initial, next-to-last, final = + -2131.73812515 -3753.43984087 -3753.72636847 + Force two-norm initial, final = 1086.21 26.3688 + Force max component initial, final = 310.811 3.92748 + Final line search alpha, max atom move = 0.00596649 0.0234333 + Iterations, force evaluations = 241 463 + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 5.8395 | 5.8395 | 5.8395 | 0.0 | 76.51 +Bond | 0.46414 | 0.46414 | 0.46414 | 0.0 | 6.08 +Kspace | 1.1535 | 1.1535 | 1.1535 | 0.0 | 15.11 +Neigh | 0.14908 | 0.14908 | 0.14908 | 0.0 | 1.95 +Comm | 0.001932 | 0.001932 | 0.001932 | 0.0 | 0.03 +Output | 0 | 0 | 0 | 0.0 | 0.00 +Modify | 0 | 0 | 0 | 0.0 | 0.00 +Other | | 0.02465 | | | 0.32 + +Nlocal: 892 ave 892 max 892 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 31 ave 31 max 31 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 148891 ave 148891 max 148891 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 148891 +Ave neighs/atom = 166.918 +Ave special neighs/atom = 10.9395 +Neighbor list builds = 15 +Dangerous builds = 0 +reset_timestep 0 + +# ------------- RUN --------------- + +thermo 100 +thermo_style multi +timestep 8 + +run_style respa 3 2 8 bond 1 dihedral 2 pair 2 kspace 3 +Respa levels: + 1 = bond angle + 2 = dihedral improper pair + 3 = kspace + +velocity all create 200.0 12345678 dist uniform +#dump dump1 all atom 100 4pti.dump + +fix 1 all nvt temp 200 300 25 +fix cor all filter/corotate m 1.0 + 163 = # of size 2 clusters + 0 = # of size 3 clusters + 25 = # of size 4 clusters + 0 = # of size 5 clusters + 100 = # of frozen angles + +run 1000 +PPPM initialization ... +WARNING: Using 12-bit tables for long-range coulomb (../kspace.cpp:321) + G vector (1/distance) = 0.203272 + grid = 16 16 16 + stencil order = 5 + estimated absolute RMS force accuracy = 0.0316399 + estimated relative force accuracy = 9.52826e-05 + using double precision FFTs + 3d grid and FFT values/proc = 9261 4096 +Per MPI rank memory allocation (min/avg/max) = 19.55 | 19.55 | 19.55 Mbytes +---------------- Step 0 ----- CPU = 0.0000 (sec) ---------------- +TotEng = -3220.3378 KinEng = 531.1804 Temp = 200.0000 +PotEng = -3751.5181 E_bond = 42.2810 E_angle = 345.2592 +E_dihed = 337.8361 E_impro = 24.2103 E_vdwl = -288.5339 +E_coul = -886.3622 E_long = -3326.2088 Press = 83.2283 +---------------- Step 100 ----- CPU = 8.4380 (sec) ---------------- +TotEng = -2718.4258 KinEng = 539.6265 Temp = 203.1802 +PotEng = -3258.0524 E_bond = 203.2307 E_angle = 566.1893 +E_dihed = 397.6759 E_impro = 34.7696 E_vdwl = -248.6577 +E_coul = -874.8466 E_long = -3336.4135 Press = 135.8640 +---------------- Step 200 ----- CPU = 16.9012 (sec) ---------------- +TotEng = -2661.9611 KinEng = 625.0674 Temp = 235.3503 +PotEng = -3287.0285 E_bond = 208.1804 E_angle = 590.8462 +E_dihed = 389.1482 E_impro = 30.5882 E_vdwl = -240.5448 +E_coul = -926.3091 E_long = -3338.9378 Press = 103.4738 +---------------- Step 300 ----- CPU = 25.3046 (sec) ---------------- +TotEng = -2662.4139 KinEng = 622.2647 Temp = 234.2951 +PotEng = -3284.6785 E_bond = 202.4210 E_angle = 573.6793 +E_dihed = 382.8919 E_impro = 41.8973 E_vdwl = -218.9895 +E_coul = -924.8414 E_long = -3341.7372 Press = 40.6746 +---------------- Step 400 ----- CPU = 33.8063 (sec) ---------------- +TotEng = -2604.9431 KinEng = 662.9890 Temp = 249.6286 +PotEng = -3267.9321 E_bond = 195.9116 E_angle = 616.1383 +E_dihed = 407.8502 E_impro = 43.3560 E_vdwl = -219.0377 +E_coul = -966.3118 E_long = -3345.8387 Press = -91.8856 +---------------- Step 500 ----- CPU = 42.3470 (sec) ---------------- +TotEng = -2609.3867 KinEng = 657.0939 Temp = 247.4090 +PotEng = -3266.4806 E_bond = 236.4955 E_angle = 570.6256 +E_dihed = 390.5111 E_impro = 41.9250 E_vdwl = -223.9927 +E_coul = -939.5249 E_long = -3342.5201 Press = 236.7471 +---------------- Step 600 ----- CPU = 50.9590 (sec) ---------------- +TotEng = -2564.7161 KinEng = 701.8494 Temp = 264.2603 +PotEng = -3266.5655 E_bond = 223.5820 E_angle = 582.7722 +E_dihed = 394.6196 E_impro = 43.8581 E_vdwl = -201.7759 +E_coul = -967.4136 E_long = -3342.2079 Press = 26.6595 +---------------- Step 700 ----- CPU = 59.4791 (sec) ---------------- +TotEng = -2510.1142 KinEng = 689.5931 Temp = 259.6455 +PotEng = -3199.7072 E_bond = 254.6476 E_angle = 611.9715 +E_dihed = 403.0624 E_impro = 44.1360 E_vdwl = -205.6377 +E_coul = -964.7455 E_long = -3343.1416 Press = 60.5789 +---------------- Step 800 ----- CPU = 67.9330 (sec) ---------------- +TotEng = -2452.7408 KinEng = 777.5962 Temp = 292.7805 +PotEng = -3230.3370 E_bond = 250.4950 E_angle = 656.6738 +E_dihed = 382.4702 E_impro = 39.5378 E_vdwl = -225.0375 +E_coul = -994.4519 E_long = -3340.0244 Press = -19.6463 +---------------- Step 900 ----- CPU = 76.3690 (sec) ---------------- +TotEng = -2339.9766 KinEng = 808.7116 Temp = 304.4961 +PotEng = -3148.6883 E_bond = 247.7657 E_angle = 679.0658 +E_dihed = 398.2984 E_impro = 43.7890 E_vdwl = -230.2498 +E_coul = -945.8152 E_long = -3341.5422 Press = -64.4343 +---------------- Step 1000 ----- CPU = 84.8757 (sec) ---------------- +TotEng = -2329.1819 KinEng = 822.9820 Temp = 309.8691 +PotEng = -3152.1639 E_bond = 264.9609 E_angle = 691.7104 +E_dihed = 385.9914 E_impro = 40.5525 E_vdwl = -230.5182 +E_coul = -954.6203 E_long = -3350.2405 Press = -146.6649 +Loop time of 84.8758 on 1 procs for 1000 steps with 892 atoms + +Performance: 8.144 ns/day, 2.947 hours/ns, 11.782 timesteps/s +32.0% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 68.548 | 68.548 | 68.548 | 0.0 | 80.76 +Bond | 10.263 | 10.263 | 10.263 | 0.0 | 12.09 +Kspace | 2.4528 | 2.4528 | 2.4528 | 0.0 | 2.89 +Neigh | 1.9041 | 1.9041 | 1.9041 | 0.0 | 2.24 +Comm | 0.044126 | 0.044126 | 0.044126 | 0.0 | 0.05 +Output | 0.000983 | 0.000983 | 0.000983 | 0.0 | 0.00 +Modify | 1.4113 | 1.4113 | 1.4113 | 0.0 | 1.66 +Other | | 0.2516 | | | 0.30 + +Nlocal: 892 ave 892 max 892 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 38 ave 38 max 38 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 144068 ave 144068 max 144068 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 144068 +Ave neighs/atom = 161.511 +Ave special neighs/atom = 10.9395 +Neighbor list builds = 190 +Dangerous builds = 0 + +unfix cor +unfix 1 + + +Please see the log.cite file for references relevant to this simulation + +Total wall time: 0:01:32 diff --git a/examples/USER/misc/filter_corotate/log.22Jun2017.bpti.g++.4 b/examples/USER/misc/filter_corotate/log.22Jun2017.bpti.g++.4 new file mode 100644 index 000000000..5367f0e62 --- /dev/null +++ b/examples/USER/misc/filter_corotate/log.22Jun2017.bpti.g++.4 @@ -0,0 +1,241 @@ +LAMMPS (20 Jun 2017) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (../comm.cpp:90) + using 1 OpenMP thread(s) per MPI task + +units real + +atom_style full +bond_style harmonic +angle_style charmm +dihedral_style charmm +improper_style harmonic + +pair_style lj/charmm/coul/long 8 10 +pair_modify mix arithmetic +kspace_style pppm 1e-4 + +read_data data.bpti + orthogonal box = (-10 -10 -30) to (50 50 30) + 1 by 2 by 2 MPI processor grid + reading atoms ... + 892 atoms + scanning bonds ... + 4 = max bonds/atom + scanning angles ... + 6 = max angles/atom + scanning dihedrals ... + 18 = max dihedrals/atom + scanning impropers ... + 2 = max impropers/atom + reading bonds ... + 906 bonds + reading angles ... + 1626 angles + reading dihedrals ... + 2501 dihedrals + reading impropers ... + 137 impropers + 4 = max # of 1-2 neighbors + 9 = max # of 1-3 neighbors + 19 = max # of 1-4 neighbors + 21 = max # of special neighbors + +special_bonds charmm +neigh_modify delay 2 every 1 + + +# ------------- MINIMIZE ---------- + +minimize 1e-4 1e-6 1000 10000 +WARNING: Resetting reneighboring criteria during minimization (../min.cpp:168) +PPPM initialization ... +WARNING: System is not charge neutral, net charge = 6 (../kspace.cpp:302) +WARNING: Using 12-bit tables for long-range coulomb (../kspace.cpp:321) + G vector (1/distance) = 0.203272 + grid = 16 16 16 + stencil order = 5 + estimated absolute RMS force accuracy = 0.0316399 + estimated relative force accuracy = 9.52826e-05 + using double precision FFTs + 3d grid and FFT values/proc = 3549 1024 +Neighbor list info ... + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 12 + ghost atom cutoff = 12 + binsize = 6, bins = 10 10 10 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/charmm/coul/long, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/3d/newton + bin: standard +Per MPI rank memory allocation (min/avg/max) = 16.97 | 17.2 | 17.52 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 0 -3075.6498 943.91164 -2131.7381 -380.67776 + 241 0 -4503.3131 749.58665 -3753.7264 -29.044989 +Loop time of 3.06327 on 4 procs for 241 steps with 892 atoms + +31.9% CPU use with 4 MPI tasks x 1 OpenMP threads + +Minimization stats: + Stopping criterion = energy tolerance + Energy initial, next-to-last, final = + -2131.73812515 -3753.4398752 -3753.72640446 + Force two-norm initial, final = 1086.21 26.3687 + Force max component initial, final = 310.811 3.92765 + Final line search alpha, max atom move = 0.0059665 0.0234343 + Iterations, force evaluations = 241 463 + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.91458 | 1.6235 | 2.2701 | 38.2 | 53.00 +Bond | 0.055164 | 0.13173 | 0.19487 | 15.1 | 4.30 +Kspace | 0.48966 | 1.1993 | 1.9847 | 48.7 | 39.15 +Neigh | 0.053297 | 0.053442 | 0.053576 | 0.0 | 1.74 +Comm | 0.031677 | 0.035006 | 0.038061 | 1.5 | 1.14 +Output | 0 | 0 | 0 | 0.0 | 0.00 +Modify | 0 | 0 | 0 | 0.0 | 0.00 +Other | | 0.02021 | | | 0.66 + +Nlocal: 223 ave 323 max 89 min +Histogram: 1 0 0 0 1 0 0 0 1 1 +Nghost: 613 ave 675 max 557 min +Histogram: 1 0 0 1 0 1 0 0 0 1 +Neighs: 37222.8 ave 50005 max 20830 min +Histogram: 1 0 0 0 1 0 0 1 0 1 + +Total # of neighbors = 148891 +Ave neighs/atom = 166.918 +Ave special neighs/atom = 10.9395 +Neighbor list builds = 15 +Dangerous builds = 0 +reset_timestep 0 + +# ------------- RUN --------------- + +thermo 100 +thermo_style multi +timestep 8 + +run_style respa 3 2 8 bond 1 dihedral 2 pair 2 kspace 3 +Respa levels: + 1 = bond angle + 2 = dihedral improper pair + 3 = kspace + +velocity all create 200.0 12345678 dist uniform +#dump dump1 all atom 100 4pti.dump + +fix 1 all nvt temp 200 300 25 +fix cor all filter/corotate m 1.0 + 163 = # of size 2 clusters + 0 = # of size 3 clusters + 25 = # of size 4 clusters + 0 = # of size 5 clusters + 100 = # of frozen angles + +run 1000 +PPPM initialization ... +WARNING: Using 12-bit tables for long-range coulomb (../kspace.cpp:321) + G vector (1/distance) = 0.203272 + grid = 16 16 16 + stencil order = 5 + estimated absolute RMS force accuracy = 0.0316399 + estimated relative force accuracy = 9.52826e-05 + using double precision FFTs + 3d grid and FFT values/proc = 3549 1024 +Per MPI rank memory allocation (min/avg/max) = 17.14 | 17.63 | 18.14 Mbytes +---------------- Step 0 ----- CPU = 0.0000 (sec) ---------------- +TotEng = -3220.3378 KinEng = 531.1804 Temp = 200.0000 +PotEng = -3751.5182 E_bond = 42.2810 E_angle = 345.2593 +E_dihed = 337.8361 E_impro = 24.2103 E_vdwl = -288.5339 +E_coul = -886.3622 E_long = -3326.2088 Press = 83.2284 +---------------- Step 100 ----- CPU = 3.4639 (sec) ---------------- +TotEng = -2718.4266 KinEng = 539.6246 Temp = 203.1794 +PotEng = -3258.0513 E_bond = 203.2306 E_angle = 566.1887 +E_dihed = 397.6756 E_impro = 34.7695 E_vdwl = -248.6577 +E_coul = -874.8446 E_long = -3336.4135 Press = 135.8653 +---------------- Step 200 ----- CPU = 6.8898 (sec) ---------------- +TotEng = -2662.0450 KinEng = 625.0178 Temp = 235.3317 +PotEng = -3287.0628 E_bond = 208.1691 E_angle = 590.8259 +E_dihed = 389.1424 E_impro = 30.5879 E_vdwl = -240.5397 +E_coul = -926.3110 E_long = -3338.9375 Press = 103.4843 +---------------- Step 300 ----- CPU = 10.2791 (sec) ---------------- +TotEng = -2661.8829 KinEng = 623.0352 Temp = 234.5852 +PotEng = -3284.9181 E_bond = 203.0274 E_angle = 573.6583 +E_dihed = 383.0124 E_impro = 41.9015 E_vdwl = -218.0696 +E_coul = -926.5806 E_long = -3341.8675 Press = 45.6868 +---------------- Step 400 ----- CPU = 13.5874 (sec) ---------------- +TotEng = -2594.5220 KinEng = 672.8693 Temp = 253.3487 +PotEng = -3267.3914 E_bond = 201.3378 E_angle = 612.7099 +E_dihed = 410.1920 E_impro = 44.0201 E_vdwl = -217.9714 +E_coul = -971.6203 E_long = -3346.0595 Press = -121.1015 +---------------- Step 500 ----- CPU = 16.9047 (sec) ---------------- +TotEng = -2603.9306 KinEng = 668.2122 Temp = 251.5952 +PotEng = -3272.1428 E_bond = 238.1081 E_angle = 578.3310 +E_dihed = 399.1305 E_impro = 41.4314 E_vdwl = -216.9664 +E_coul = -969.4047 E_long = -3342.7729 Press = 156.7851 +---------------- Step 600 ----- CPU = 20.1970 (sec) ---------------- +TotEng = -2531.1096 KinEng = 728.1698 Temp = 274.1705 +PotEng = -3259.2794 E_bond = 232.8396 E_angle = 621.3323 +E_dihed = 398.1952 E_impro = 37.0914 E_vdwl = -241.6350 +E_coul = -963.1540 E_long = -3343.9488 Press = 58.6784 +---------------- Step 700 ----- CPU = 23.4360 (sec) ---------------- +TotEng = -2499.9495 KinEng = 742.1211 Temp = 279.4234 +PotEng = -3242.0705 E_bond = 240.5622 E_angle = 582.9270 +E_dihed = 396.6246 E_impro = 36.6510 E_vdwl = -228.4925 +E_coul = -926.8734 E_long = -3343.4695 Press = -60.7458 +---------------- Step 800 ----- CPU = 26.6709 (sec) ---------------- +TotEng = -2426.0217 KinEng = 760.1083 Temp = 286.1959 +PotEng = -3186.1300 E_bond = 266.5863 E_angle = 652.3401 +E_dihed = 380.7407 E_impro = 34.6861 E_vdwl = -225.3729 +E_coul = -953.2382 E_long = -3341.8721 Press = -57.9824 +---------------- Step 900 ----- CPU = 29.8152 (sec) ---------------- +TotEng = -2419.4636 KinEng = 780.8361 Temp = 294.0004 +PotEng = -3200.2996 E_bond = 269.3237 E_angle = 665.7171 +E_dihed = 408.3527 E_impro = 43.7811 E_vdwl = -254.0696 +E_coul = -1002.0694 E_long = -3331.3352 Press = -52.0169 +---------------- Step 1000 ----- CPU = 32.8748 (sec) ---------------- +TotEng = -2398.7244 KinEng = 811.9856 Temp = 305.7288 +PotEng = -3210.7099 E_bond = 258.2207 E_angle = 639.3671 +E_dihed = 379.3353 E_impro = 41.7602 E_vdwl = -207.2654 +E_coul = -983.9330 E_long = -3338.1948 Press = 89.4870 +Loop time of 32.8751 on 4 procs for 1000 steps with 892 atoms + +Performance: 21.025 ns/day, 1.141 hours/ns, 30.418 timesteps/s +31.9% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 12.449 | 19.023 | 24.612 | 99.6 | 57.86 +Bond | 1.4547 | 2.8768 | 3.9098 | 61.4 | 8.75 +Kspace | 1.0537 | 1.0778 | 1.0992 | 2.1 | 3.28 +Neigh | 0.67542 | 0.67994 | 0.68323 | 0.3 | 2.07 +Comm | 1.8602 | 8.4515 | 16.516 | 182.9 | 25.71 +Output | 0.000839 | 0.00147 | 0.003293 | 2.7 | 0.00 +Modify | 0.56658 | 0.63186 | 0.69304 | 6.8 | 1.92 +Other | | 0.133 | | | 0.40 + +Nlocal: 223 ave 339 max 136 min +Histogram: 1 1 0 0 0 1 0 0 0 1 +Nghost: 590 ave 626 max 552 min +Histogram: 1 0 0 0 1 0 1 0 0 1 +Neighs: 36488.2 ave 41965 max 29054 min +Histogram: 1 0 0 0 1 0 0 0 1 1 + +Total # of neighbors = 145953 +Ave neighs/atom = 163.624 +Ave special neighs/atom = 10.9395 +Neighbor list builds = 189 +Dangerous builds = 0 + +unfix cor +unfix 1 + + +Please see the log.cite file for references relevant to this simulation + +Total wall time: 0:00:36 diff --git a/examples/USER/misc/filter_corotate/log.22Jun2017.peptide.g++.1 b/examples/USER/misc/filter_corotate/log.22Jun2017.peptide.g++.1 new file mode 100644 index 000000000..22c5483c9 --- /dev/null +++ b/examples/USER/misc/filter_corotate/log.22Jun2017.peptide.g++.1 @@ -0,0 +1,147 @@ +LAMMPS (20 Jun 2017) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (../comm.cpp:90) + using 1 OpenMP thread(s) per MPI task +# Solvated 5-mer peptide, run for 8ps in NVT + +units real +atom_style full + +pair_style lj/charmm/coul/long 8.0 10.0 10.0 +bond_style harmonic +angle_style charmm +dihedral_style charmm +improper_style harmonic +kspace_style pppm 0.0001 + +read_data data.peptide + orthogonal box = (36.8402 41.0137 29.7681) to (64.2116 68.3851 57.1395) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 2004 atoms + reading velocities ... + 2004 velocities + scanning bonds ... + 3 = max bonds/atom + scanning angles ... + 6 = max angles/atom + scanning dihedrals ... + 14 = max dihedrals/atom + scanning impropers ... + 1 = max impropers/atom + reading bonds ... + 1365 bonds + reading angles ... + 786 angles + reading dihedrals ... + 207 dihedrals + reading impropers ... + 12 impropers + 4 = max # of 1-2 neighbors + 7 = max # of 1-3 neighbors + 14 = max # of 1-4 neighbors + 18 = max # of special neighbors + +neighbor 2.0 bin +neigh_modify delay 5 + +thermo 50 +#dump dump1 all atom 100 peptide.dump + +timestep 8 + +run_style respa 3 2 8 bond 1 dihedral 2 pair 2 kspace 3 +Respa levels: + 1 = bond angle + 2 = dihedral improper pair + 3 = kspace + +fix 1 all nvt temp 250.0 250.0 100.0 tchain 1 +fix cor all filter/corotate m 1.0 + 19 = # of size 2 clusters + 0 = # of size 3 clusters + 3 = # of size 4 clusters + 0 = # of size 5 clusters + 646 = # of frozen angles +run 1000 +PPPM initialization ... +WARNING: Using 12-bit tables for long-range coulomb (../kspace.cpp:321) + G vector (1/distance) = 0.268725 + grid = 15 15 15 + stencil order = 5 + estimated absolute RMS force accuracy = 0.0228209 + estimated relative force accuracy = 6.87243e-05 + using double precision FFTs + 3d grid and FFT values/proc = 10648 3375 +Neighbor list info ... + update every 1 steps, delay 5 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 12 + ghost atom cutoff = 12 + binsize = 6, bins = 5 5 5 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/charmm/coul/long, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/3d/newton + bin: standard +Per MPI rank memory allocation (min/avg/max) = 22.72 | 22.72 | 22.72 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 190.0857 -6442.7438 70.391457 -5237.4338 20361.984 + 50 239.47667 -7205.1006 1092.7664 -4682.5237 -23733.122 + 100 244.63086 -6788.0793 422.97204 -4904.5234 16458.011 + 150 240.79042 -7267.0791 966.31411 -4863.1107 -13554.894 + 200 254.77122 -6868.5713 591.00071 -4756.4431 10532.563 + 250 241.87417 -7264.9349 856.9357 -4963.8743 -9043.4359 + 300 251.37775 -6976.8 650.55612 -4825.3773 6986.2021 + 350 250.81494 -7286.7011 880.11184 -4909.0829 -6392.4665 + 400 247.55673 -7104.4036 701.89555 -4924.4551 4720.7811 + 450 258.54988 -7215.3011 832.23692 -4839.3759 -3446.3859 + 500 246.80928 -7151.2468 715.61007 -4962.0464 2637.5769 + 550 246.20721 -7159.0464 805.24974 -4883.8011 -2725.227 + 600 250.62483 -7201.7688 806.10076 -4899.2968 770.22352 + 650 247.59777 -7260.1607 802.97277 -4978.8899 -430.42309 + 700 246.86951 -7286.2971 825.99865 -4986.3486 -427.88651 + 750 252.79268 -7307.8572 833.4822 -4965.0605 -614.74372 + 800 251.73191 -7315.2457 839.59859 -4972.666 952.56448 + 850 246.75844 -7303.6221 816.67112 -5013.6642 -2055.2823 + 900 251.00123 -7317.4219 825.12165 -4993.6817 -356.53166 + 950 259.20822 -7252.3466 854.62611 -4850.1016 -1719.5267 + 1000 245.72486 -7347.5547 811.48146 -5068.9576 -717.6136 +Loop time of 357.523 on 1 procs for 1000 steps with 2004 atoms + +Performance: 1.933 ns/day, 12.414 hours/ns, 2.797 timesteps/s +32.0% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 328.2 | 328.2 | 328.2 | 0.0 | 91.80 +Bond | 4.4815 | 4.4815 | 4.4815 | 0.0 | 1.25 +Kspace | 3.9448 | 3.9448 | 3.9448 | 0.0 | 1.10 +Neigh | 12.457 | 12.457 | 12.457 | 0.0 | 3.48 +Comm | 3.2147 | 3.2147 | 3.2147 | 0.0 | 0.90 +Output | 0.001689 | 0.001689 | 0.001689 | 0.0 | 0.00 +Modify | 3.937 | 3.937 | 3.937 | 0.0 | 1.10 +Other | | 1.289 | | | 0.36 + +Nlocal: 2004 ave 2004 max 2004 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 11191 ave 11191 max 11191 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 708610 ave 708610 max 708610 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 708610 +Ave neighs/atom = 353.598 +Ave special neighs/atom = 2.34032 +Neighbor list builds = 200 +Dangerous builds = 200 +unfix cor +unfix 1 + + + + +Please see the log.cite file for references relevant to this simulation + +Total wall time: 0:05:57 diff --git a/examples/USER/misc/filter_corotate/log.22Jun2017.peptide.g++.4 b/examples/USER/misc/filter_corotate/log.22Jun2017.peptide.g++.4 new file mode 100644 index 000000000..eec3843bd --- /dev/null +++ b/examples/USER/misc/filter_corotate/log.22Jun2017.peptide.g++.4 @@ -0,0 +1,147 @@ +LAMMPS (20 Jun 2017) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (../comm.cpp:90) + using 1 OpenMP thread(s) per MPI task +# Solvated 5-mer peptide, run for 8ps in NVT + +units real +atom_style full + +pair_style lj/charmm/coul/long 8.0 10.0 10.0 +bond_style harmonic +angle_style charmm +dihedral_style charmm +improper_style harmonic +kspace_style pppm 0.0001 + +read_data data.peptide + orthogonal box = (36.8402 41.0137 29.7681) to (64.2116 68.3851 57.1395) + 1 by 2 by 2 MPI processor grid + reading atoms ... + 2004 atoms + reading velocities ... + 2004 velocities + scanning bonds ... + 3 = max bonds/atom + scanning angles ... + 6 = max angles/atom + scanning dihedrals ... + 14 = max dihedrals/atom + scanning impropers ... + 1 = max impropers/atom + reading bonds ... + 1365 bonds + reading angles ... + 786 angles + reading dihedrals ... + 207 dihedrals + reading impropers ... + 12 impropers + 4 = max # of 1-2 neighbors + 7 = max # of 1-3 neighbors + 14 = max # of 1-4 neighbors + 18 = max # of special neighbors + +neighbor 2.0 bin +neigh_modify delay 5 + +thermo 50 +#dump dump1 all atom 100 peptide.dump + +timestep 8 + +run_style respa 3 2 8 bond 1 dihedral 2 pair 2 kspace 3 +Respa levels: + 1 = bond angle + 2 = dihedral improper pair + 3 = kspace + +fix 1 all nvt temp 250.0 250.0 100.0 tchain 1 +fix cor all filter/corotate m 1.0 + 19 = # of size 2 clusters + 0 = # of size 3 clusters + 3 = # of size 4 clusters + 0 = # of size 5 clusters + 646 = # of frozen angles +run 1000 +PPPM initialization ... +WARNING: Using 12-bit tables for long-range coulomb (../kspace.cpp:321) + G vector (1/distance) = 0.268725 + grid = 15 15 15 + stencil order = 5 + estimated absolute RMS force accuracy = 0.0228209 + estimated relative force accuracy = 6.87243e-05 + using double precision FFTs + 3d grid and FFT values/proc = 4312 960 +Neighbor list info ... + update every 1 steps, delay 5 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 12 + ghost atom cutoff = 12 + binsize = 6, bins = 5 5 5 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/charmm/coul/long, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/3d/newton + bin: standard +Per MPI rank memory allocation (min/avg/max) = 16.87 | 17.05 | 17.26 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 190.0857 -6442.7438 70.391457 -5237.4338 20361.984 + 50 239.47667 -7205.1005 1092.7664 -4682.5237 -23733.122 + 100 244.63889 -6788.1152 422.96733 -4904.5161 16457.756 + 150 239.36917 -7258.7053 967.87775 -4861.6589 -13526.261 + 200 255.14702 -6864.0525 604.58036 -4736.1009 11013.1 + 250 252.72919 -7303.0966 898.11178 -4896.0494 -8480.8766 + 300 250.66477 -6989.2603 652.83649 -4839.8141 6209.3375 + 350 243.30794 -7218.8575 838.31977 -4927.8525 -5180.4928 + 400 256.3573 -7090.677 706.24197 -4853.8377 3302.577 + 450 246.15776 -7274.574 834.31676 -4970.557 -3427.971 + 500 256.28473 -7082.1447 735.42828 -4816.5524 2846.086 + 550 251.32327 -7341.739 812.64934 -5028.5484 -1786.9277 + 600 254.57737 -7152.3448 740.52534 -4891.8494 825.91675 + 650 244.95305 -7207.1136 790.67659 -4953.9295 -520.79769 + 700 249.4984 -7204.2699 779.06969 -4935.5544 -940.75384 + 750 248.46962 -7232.1037 791.6642 -4956.9361 -548.12171 + 800 260.2974 -7293.1982 793.23282 -4945.8435 -1171.26 + 850 249.79023 -7258.3759 823.56789 -4943.4198 -499.76275 + 900 249.97237 -7267.0584 784.57992 -4990.0028 -271.33531 + 950 251.29018 -7261.0642 823.467 -4937.2534 -538.7168 + 1000 246.05777 -7285.0948 847.90892 -4968.0826 -2613.1854 +Loop time of 94.6835 on 4 procs for 1000 steps with 2004 atoms + +Performance: 7.300 ns/day, 3.288 hours/ns, 10.562 timesteps/s +37.9% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 33.389 | 78.508 | 94.639 | 294.1 | 82.92 +Bond | 0.39957 | 1.104 | 1.4443 | 40.6 | 1.17 +Kspace | 0.53324 | 1.2631 | 1.5137 | 37.5 | 1.33 +Neigh | 1.2668 | 3.011 | 3.5942 | 58.0 | 3.18 +Comm | 3.4563 | 8.8707 | 11.494 | 107.9 | 9.37 +Output | 0.000435 | 0.0017425 | 0.004136 | 3.4 | 0.00 +Modify | 0.59335 | 1.4123 | 1.6921 | 39.8 | 1.49 +Other | | 0.5129 | | | 0.54 + +Nlocal: 501 ave 515 max 476 min +Histogram: 1 0 0 0 0 0 0 1 1 1 +Nghost: 6681.5 ave 6740 max 6634 min +Histogram: 2 0 0 0 0 0 0 1 0 1 +Neighs: 176872 ave 182642 max 168464 min +Histogram: 1 0 0 0 0 0 1 1 0 1 + +Total # of neighbors = 707486 +Ave neighs/atom = 353.037 +Ave special neighs/atom = 2.34032 +Neighbor list builds = 200 +Dangerous builds = 200 +unfix cor +unfix 1 + + + + +Please see the log.cite file for references relevant to this simulation + +Total wall time: 0:01:53 diff --git a/src/CORESHELL/compute_temp_cs.h b/src/CORESHELL/compute_temp_cs.h index 5a1d1434c..3e93e4a68 100644 --- a/src/CORESHELL/compute_temp_cs.h +++ b/src/CORESHELL/compute_temp_cs.h @@ -1,109 +1,109 @@ -/* ---------------------------------------------------------------------- +/* -*- 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 COMPUTE_CLASS ComputeStyle(temp/cs,ComputeTempCS) #else #ifndef LMP_COMPUTE_TEMP_CS_H #define LMP_COMPUTE_TEMP_CS_H #include "compute.h" namespace LAMMPS_NS { class ComputeTempCS : public Compute { public: ComputeTempCS(class LAMMPS *, int, char **); ~ComputeTempCS(); void init(); void setup(); double compute_scalar(); void compute_vector(); double memory_usage(); void remove_bias(int, double *); void remove_bias_all(); void reapply_bias_all(); void restore_bias(int, double *); void restore_bias_all(); int pack_reverse_comm(int, int, double *); void unpack_reverse_comm(int, int *, double *); private: int groupbit_c,groupbit_s; int nshells; int firstflag; int maxatom; int cgroup,sgroup; double tfactor; double **vint; char *id_fix; class FixStore *fix; void dof_compute(); void vcm_pairs(); }; } #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: Compute temp/cs used when bonds are not allowed This compute only works on pairs of bonded particles. E: Cannot find specified group ID for core particles Self-explanatory. E: Cannot find specified group ID for shell particles Self-explanatory. E: Compute temp/cs requires ghost atoms store velocity Use the comm_modify vel yes command to enable this. E: Number of core atoms != number of shell atoms There must be a one-to-one pairing of core and shell atoms. E: Core/shell partner atom not found Could not find one of the atoms in the bond pair. E: Core/shell partners were not all found Could not find or more atoms in the bond pairs. E: Temperature compute degrees of freedom < 0 This should not happen if you are calculating the temperature on a valid set of atoms. */ diff --git a/src/CORESHELL/pair_born_coul_long_cs.h b/src/CORESHELL/pair_born_coul_long_cs.h index d2c8c0484..68c29e4fc 100644 --- a/src/CORESHELL/pair_born_coul_long_cs.h +++ b/src/CORESHELL/pair_born_coul_long_cs.h @@ -1,63 +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 PAIR_CLASS PairStyle(born/coul/long/cs,PairBornCoulLongCS) #else #ifndef LMP_PAIR_BORN_COUL_LONG_CS_H #define LMP_PAIR_BORN_COUL_LONG_CS_H #include "pair_born_coul_long.h" namespace LAMMPS_NS { class PairBornCoulLongCS : public PairBornCoulLong { public: PairBornCoulLongCS(class LAMMPS *); virtual void compute(int, 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: Incorrect args for pair coefficients Self-explanatory. Check the input script or data file. 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: Pair style born/coul/long requires atom attribute q An atom style that defines this attribute must be used. E: Pair style requires a KSpace style No kspace style is defined. */ diff --git a/src/CORESHELL/pair_buck_coul_long_cs.h b/src/CORESHELL/pair_buck_coul_long_cs.h index 7f0bc149c..d6b117d67 100644 --- a/src/CORESHELL/pair_buck_coul_long_cs.h +++ b/src/CORESHELL/pair_buck_coul_long_cs.h @@ -1,63 +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 PAIR_CLASS PairStyle(buck/coul/long/cs,PairBuckCoulLongCS) #else #ifndef LMP_PAIR_BUCK_COUL_LONG_CS_H #define LMP_PAIR_BUCK_COUL_LONG_CS_H #include "pair_buck_coul_long.h" namespace LAMMPS_NS { class PairBuckCoulLongCS : public PairBuckCoulLong { public: PairBuckCoulLongCS(class LAMMPS *); virtual void compute(int, 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: Incorrect args for pair coefficients Self-explanatory. Check the input script or data file. 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: Pair style buck/coul/long requires atom attribute q The atom style defined does not have these attributes. E: Pair style requires a KSpace style No kspace style is defined. */ diff --git a/src/GPU/pair_lj_cubic_gpu.h b/src/GPU/pair_lj_cubic_gpu.h index 1591eb8b9..cdfc157e8 100644 --- a/src/GPU/pair_lj_cubic_gpu.h +++ b/src/GPU/pair_lj_cubic_gpu.h @@ -1,58 +1,58 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(lj/cubic/gpu,PairLJCubicGPU) #else #ifndef LMP_PAIR_LJ_CUBIC_GPU_H #define LMP_PAIR_LJ_CUBIC_GPU_H #include "pair_lj_cubic.h" namespace LAMMPS_NS { class PairLJCubicGPU : public PairLJCubic { public: PairLJCubicGPU(LAMMPS *lmp); ~PairLJCubicGPU(); void cpu_compute(int, int, int, int, int *, int *, int **); void compute(int, int); void init_style(); double memory_usage(); enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH }; private: int gpu_mode; double cpu_time; }; } #endif #endif /* ERROR/WARNING messages: E: Insufficient memory on accelerator There is insufficient memory on one of the devices specified for the gpu package E: Cannot use newton pair with lj/cubic/gpu pair style Self-explanatory. */ diff --git a/src/GPU/pair_tersoff_gpu.h b/src/GPU/pair_tersoff_gpu.h index 4fa358a6b..ed3dadef5 100644 --- a/src/GPU/pair_tersoff_gpu.h +++ b/src/GPU/pair_tersoff_gpu.h @@ -1,70 +1,70 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(tersoff/gpu,PairTersoffGPU) #else #ifndef LMP_PAIR_TERSOFF_GPU_H #define LMP_PAIR_TERSOFF_GPU_H #include "pair_tersoff.h" namespace LAMMPS_NS { class PairTersoffGPU : public PairTersoff { public: PairTersoffGPU(class LAMMPS *); ~PairTersoffGPU(); void compute(int, int); double init_one(int, int); void init_style(); enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH }; protected: void allocate(); int gpu_mode; double cpu_time; int *gpulist; }; } #endif #endif /* ERROR/WARNING messages: E: Insufficient memory on accelerator There is insufficient memory on one of the devices specified for the gpu package E: Pair style tersoff/gpu requires atom IDs This is a requirement to use the tersoff/gpu potential. E: Pair style tersoff/gpu requires newton pair off See the newton command. This is a restriction to use this pair style. 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. */ diff --git a/src/GPU/pair_tersoff_mod_gpu.h b/src/GPU/pair_tersoff_mod_gpu.h index 6d3017669..3967e90a7 100644 --- a/src/GPU/pair_tersoff_mod_gpu.h +++ b/src/GPU/pair_tersoff_mod_gpu.h @@ -1,67 +1,67 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(tersoff/mod/gpu,PairTersoffMODGPU) #else #ifndef LMP_PAIR_TERSOFF_MOD_GPU_H #define LMP_PAIR_TERSOFF_MOD_GPU_H #include "pair_tersoff_mod.h" namespace LAMMPS_NS { class PairTersoffMODGPU : public PairTersoffMOD { public: PairTersoffMODGPU(class LAMMPS *); ~PairTersoffMODGPU(); void compute(int, int); double init_one(int, int); void init_style(); enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH }; protected: void allocate(); int gpu_mode; double cpu_time; int *gpulist; }; } #endif #endif /* ERROR/WARNING messages: E: Insufficient memory on accelerator There is insufficient memory on one of the devices specified for the gpu package E: Pair style tersoff/gpu requires newton pair off See the newton command. This is a restriction to use this pair style. 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. */ diff --git a/src/GPU/pair_tersoff_zbl_gpu.h b/src/GPU/pair_tersoff_zbl_gpu.h index 003e037bb..ba923ffd2 100644 --- a/src/GPU/pair_tersoff_zbl_gpu.h +++ b/src/GPU/pair_tersoff_zbl_gpu.h @@ -1,67 +1,67 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(tersoff/zbl/gpu,PairTersoffZBLGPU) #else #ifndef LMP_PAIR_TERSOFF_ZBL_GPU_H #define LMP_PAIR_TERSOFF_ZBL_GPU_H #include "pair_tersoff_zbl.h" namespace LAMMPS_NS { class PairTersoffZBLGPU : public PairTersoffZBL { public: PairTersoffZBLGPU(class LAMMPS *); ~PairTersoffZBLGPU(); void compute(int, int); double init_one(int, int); void init_style(); enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH }; protected: void allocate(); int gpu_mode; double cpu_time; int *gpulist; }; } #endif #endif /* ERROR/WARNING messages: E: Insufficient memory on accelerator There is insufficient memory on one of the devices specified for the gpu package E: Pair style tersoff/gpu requires newton pair off See the newton command. This is a restriction to use this pair style. 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. */ diff --git a/src/GPU/pair_zbl_gpu.h b/src/GPU/pair_zbl_gpu.h index 950fe952d..3e6ac3739 100644 --- a/src/GPU/pair_zbl_gpu.h +++ b/src/GPU/pair_zbl_gpu.h @@ -1,58 +1,58 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(zbl/gpu,PairZBLGPU) #else #ifndef LMP_PAIR_ZBL_GPU_H #define LMP_PAIR_ZBL_GPU_H #include "pair_zbl.h" namespace LAMMPS_NS { class PairZBLGPU : public PairZBL { public: PairZBLGPU(LAMMPS *lmp); ~PairZBLGPU(); void cpu_compute(int, int, int, int, int *, int *, int **); void compute(int, int); void init_style(); double memory_usage(); enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH }; private: int gpu_mode; double cpu_time; }; } #endif #endif /* ERROR/WARNING messages: E: Insufficient memory on accelerator There is insufficient memory on one of the devices specified for the gpu package E: Cannot use newton pair with zbl/gpu pair style Self-explanatory. */ diff --git a/src/KOKKOS/pair_buck_kokkos.h b/src/KOKKOS/pair_buck_kokkos.h index d57e320e9..2691f1092 100644 --- a/src/KOKKOS/pair_buck_kokkos.h +++ b/src/KOKKOS/pair_buck_kokkos.h @@ -1,129 +1,129 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(buck/kk,PairBuckKokkos) PairStyle(buck/kk/device,PairBuckKokkos) PairStyle(buck/kk/host,PairBuckKokkos) #else #ifndef LMP_PAIR_BUCK_KOKKOS_H #define LMP_PAIR_BUCK_KOKKOS_H #include "pair_kokkos.h" #include "pair_buck.h" #include "neigh_list_kokkos.h" namespace LAMMPS_NS { template class PairBuckKokkos : public PairBuck { public: enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2}; enum {COUL_FLAG=0}; typedef DeviceType device_type; typedef ArrayTypes AT; PairBuckKokkos(class LAMMPS *); ~PairBuckKokkos(); void compute(int, int); void init_style(); double init_one(int, int); struct params_buck{ KOKKOS_INLINE_FUNCTION params_buck(){cutsq=0;a=0;c=0;rhoinv=0;buck1=0;buck2=0;offset=0;}; KOKKOS_INLINE_FUNCTION params_buck(int i){cutsq=0;a=0;c=0;rhoinv=0;buck1=0;buck2=0;offset=0;}; F_FLOAT cutsq,a,c,rhoinv,buck1,buck2,offset; }; protected: void cleanup_copy() {} template KOKKOS_INLINE_FUNCTION F_FLOAT compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const; template KOKKOS_INLINE_FUNCTION F_FLOAT compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const; template KOKKOS_INLINE_FUNCTION F_FLOAT compute_ecoul(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const { return 0; } Kokkos::DualView k_params; typename Kokkos::DualView::t_dev_const_um params; params_buck m_params[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; // hardwired to space for 12 atom types F_FLOAT m_cutsq[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; typename AT::t_x_array_randomread x; typename AT::t_x_array c_x; typename AT::t_f_array f; typename AT::t_int_1d_randomread type; typename AT::t_tagint_1d tag; DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; typename AT::t_efloat_1d d_eatom; typename AT::t_virial_array d_vatom; int newton_pair; double special_lj[4]; typename AT::tdual_ffloat_2d k_cutsq; typename AT::t_ffloat_2d d_cutsq; int neighflag; int nlocal,nall,eflag,vflag; void allocate(); friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; friend EV_FLOAT pair_compute_neighlist(PairBuckKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute_neighlist(PairBuckKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute_neighlist(PairBuckKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute_neighlist(PairBuckKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute(PairBuckKokkos*,NeighListKokkos*); friend void pair_virial_fdotr_compute(PairBuckKokkos*); }; } #endif #endif /* ERROR/WARNING messages: E: Cannot use Kokkos pair style with rRESPA inner/middle Self-explanatory. E: Cannot use chosen neighbor list style with buck/kk That style is not supported by Kokkos. */ diff --git a/src/KOKKOS/pair_sw_kokkos.h b/src/KOKKOS/pair_sw_kokkos.h index d899edfc1..b94e39335 100644 --- a/src/KOKKOS/pair_sw_kokkos.h +++ b/src/KOKKOS/pair_sw_kokkos.h @@ -1,162 +1,162 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(sw/kk,PairSWKokkos) PairStyle(sw/kk/device,PairSWKokkos) PairStyle(sw/kk/host,PairSWKokkos) #else #ifndef LMP_PAIR_SW_KOKKOS_H #define LMP_PAIR_SW_KOKKOS_H #include "pair_sw.h" #include "pair_kokkos.h" template struct TagPairSWComputeHalf{}; template struct TagPairSWComputeFullA{}; template struct TagPairSWComputeFullB{}; struct TagPairSWComputeShortNeigh{}; namespace LAMMPS_NS { template class PairSWKokkos : public PairSW { public: enum {EnabledNeighFlags=FULL}; enum {COUL_FLAG=0}; typedef DeviceType device_type; typedef ArrayTypes AT; typedef EV_FLOAT value_type; PairSWKokkos(class LAMMPS *); virtual ~PairSWKokkos(); virtual void compute(int, int); virtual void coeff(int, char **); virtual void init_style(); template KOKKOS_INLINE_FUNCTION void operator()(TagPairSWComputeHalf, const int&, EV_FLOAT&) const; template KOKKOS_INLINE_FUNCTION void operator()(TagPairSWComputeHalf, const int&) const; template KOKKOS_INLINE_FUNCTION void operator()(TagPairSWComputeFullA, const int&, EV_FLOAT&) const; template KOKKOS_INLINE_FUNCTION void operator()(TagPairSWComputeFullA, const int&) const; template KOKKOS_INLINE_FUNCTION void operator()(TagPairSWComputeFullB, const int&, EV_FLOAT&) const; template KOKKOS_INLINE_FUNCTION void operator()(TagPairSWComputeFullB, const int&) const; KOKKOS_INLINE_FUNCTION void operator()(TagPairSWComputeShortNeigh, const int&) const; template KOKKOS_INLINE_FUNCTION void ev_tally(EV_FLOAT &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 ev_tally3(EV_FLOAT &ev, const int &i, const int &j, int &k, const F_FLOAT &evdwl, const F_FLOAT &ecoul, F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *drji, F_FLOAT *drki) const; KOKKOS_INLINE_FUNCTION void ev_tally3_atom(EV_FLOAT &ev, const int &i, const F_FLOAT &evdwl, const F_FLOAT &ecoul, F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *drji, F_FLOAT *drki) const; protected: typedef Kokkos::DualView tdual_int_3d; typedef typename tdual_int_3d::t_dev_const_randomread t_int_3d_randomread; typedef typename tdual_int_3d::t_host t_host_int_3d; t_int_3d_randomread d_elem2param; DAT::t_int_1d_randomread d_map; typedef Kokkos::DualView tdual_param_1d; typedef typename tdual_param_1d::t_dev t_param_1d; typedef typename tdual_param_1d::t_host t_host_param_1d; t_param_1d d_params; virtual void setup_params(); void twobody(const Param&, const F_FLOAT&, F_FLOAT&, const int&, F_FLOAT&) const; void threebody(const Param&, const Param&, const Param&, const F_FLOAT&, const F_FLOAT&, F_FLOAT *, F_FLOAT *, F_FLOAT *, F_FLOAT *, const int&, F_FLOAT&) const; void threebodyj(const Param&, const Param&, const Param&, const F_FLOAT&, const F_FLOAT&, F_FLOAT *, F_FLOAT *, F_FLOAT *) const; typename AT::t_x_array_randomread x; typename AT::t_f_array f; typename AT::t_tagint_1d tag; typename AT::t_int_1d_randomread type; DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; typename ArrayTypes::t_efloat_1d d_eatom; typename ArrayTypes::t_virial_array d_vatom; DAT::t_int_1d_randomread d_type2frho; DAT::t_int_2d_randomread d_type2rhor; DAT::t_int_2d_randomread d_type2z2r; typename AT::t_neighbors_2d d_neighbors; typename AT::t_int_1d_randomread d_ilist; typename AT::t_int_1d_randomread d_numneigh; //NeighListKokkos k_list; int neighflag,newton_pair; int nlocal,nall,eflag,vflag; int inum; Kokkos::View d_neighbors_short; Kokkos::View d_numneigh_short; friend void pair_virial_fdotr_compute(PairSWKokkos*); }; } #endif #endif /* ERROR/WARNING messages: E: Cannot use chosen neighbor list style with pair sw/kk Self-explanatory. */ diff --git a/src/KOKKOS/pair_vashishta_kokkos.h b/src/KOKKOS/pair_vashishta_kokkos.h index 49c936185..174db2cb9 100644 --- a/src/KOKKOS/pair_vashishta_kokkos.h +++ b/src/KOKKOS/pair_vashishta_kokkos.h @@ -1,162 +1,162 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(vashishta/kk,PairVashishtaKokkos) PairStyle(vashishta/kk/device,PairVashishtaKokkos) PairStyle(vashishta/kk/host,PairVashishtaKokkos) #else #ifndef LMP_PAIR_VASHISHTA_KOKKOS_H #define LMP_PAIR_VASHISHTA_KOKKOS_H #include "pair_vashishta.h" #include "pair_kokkos.h" template struct TagPairVashishtaComputeHalf{}; template struct TagPairVashishtaComputeFullA{}; template struct TagPairVashishtaComputeFullB{}; struct TagPairVashishtaComputeShortNeigh{}; namespace LAMMPS_NS { template class PairVashishtaKokkos : public PairVashishta { public: enum {EnabledNeighFlags=FULL}; enum {COUL_FLAG=0}; typedef DeviceType device_type; typedef ArrayTypes AT; typedef EV_FLOAT value_type; PairVashishtaKokkos(class LAMMPS *); virtual ~PairVashishtaKokkos(); virtual void compute(int, int); virtual void coeff(int, char **); virtual void init_style(); template KOKKOS_INLINE_FUNCTION void operator()(TagPairVashishtaComputeHalf, const int&, EV_FLOAT&) const; template KOKKOS_INLINE_FUNCTION void operator()(TagPairVashishtaComputeHalf, const int&) const; template KOKKOS_INLINE_FUNCTION void operator()(TagPairVashishtaComputeFullA, const int&, EV_FLOAT&) const; template KOKKOS_INLINE_FUNCTION void operator()(TagPairVashishtaComputeFullA, const int&) const; template KOKKOS_INLINE_FUNCTION void operator()(TagPairVashishtaComputeFullB, const int&, EV_FLOAT&) const; template KOKKOS_INLINE_FUNCTION void operator()(TagPairVashishtaComputeFullB, const int&) const; KOKKOS_INLINE_FUNCTION void operator()(TagPairVashishtaComputeShortNeigh, const int&) const; template KOKKOS_INLINE_FUNCTION void ev_tally(EV_FLOAT &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 ev_tally3(EV_FLOAT &ev, const int &i, const int &j, int &k, const F_FLOAT &evdwl, const F_FLOAT &ecoul, F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *drji, F_FLOAT *drki) const; KOKKOS_INLINE_FUNCTION void ev_tally3_atom(EV_FLOAT &ev, const int &i, const F_FLOAT &evdwl, const F_FLOAT &ecoul, F_FLOAT *fj, F_FLOAT *fk, F_FLOAT *drji, F_FLOAT *drki) const; protected: typedef Kokkos::DualView tdual_int_3d; typedef typename tdual_int_3d::t_dev_const_randomread t_int_3d_randomread; typedef typename tdual_int_3d::t_host t_host_int_3d; t_int_3d_randomread d_elem2param; DAT::t_int_1d_randomread d_map; typedef Kokkos::DualView tdual_param_1d; typedef typename tdual_param_1d::t_dev t_param_1d; typedef typename tdual_param_1d::t_host t_host_param_1d; t_param_1d d_params; virtual void setup_params(); void twobody(const Param&, const F_FLOAT&, F_FLOAT&, const int&, F_FLOAT&) const; void threebody(const Param&, const Param&, const Param&, const F_FLOAT&, const F_FLOAT&, F_FLOAT *, F_FLOAT *, F_FLOAT *, F_FLOAT *, const int&, F_FLOAT&) const; void threebodyj(const Param&, const Param&, const Param&, const F_FLOAT&, const F_FLOAT&, F_FLOAT *, F_FLOAT *, F_FLOAT *) const; typename AT::t_x_array_randomread x; typename AT::t_f_array f; typename AT::t_tagint_1d tag; typename AT::t_int_1d_randomread type; DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; typename ArrayTypes::t_efloat_1d d_eatom; typename ArrayTypes::t_virial_array d_vatom; DAT::t_int_1d_randomread d_type2frho; DAT::t_int_2d_randomread d_type2rhor; DAT::t_int_2d_randomread d_type2z2r; typename AT::t_neighbors_2d d_neighbors; typename AT::t_int_1d_randomread d_ilist; typename AT::t_int_1d_randomread d_numneigh; //NeighListKokkos k_list; int neighflag,newton_pair; int nlocal,nall,eflag,vflag; int inum; Kokkos::View d_neighbors_short_2body; Kokkos::View d_numneigh_short_2body; Kokkos::View d_neighbors_short_3body; Kokkos::View d_numneigh_short_3body; friend void pair_virial_fdotr_compute(PairVashishtaKokkos*); }; } #endif #endif /* ERROR/WARNING messages: E: Cannot use chosen neighbor list style with pair vashishta/kk Self-explanatory. */ diff --git a/src/KSPACE/pair_lj_long_tip4p_long.cpp b/src/KSPACE/pair_lj_long_tip4p_long.cpp index d2a6b801f..1dc1ca1cb 100644 --- a/src/KSPACE/pair_lj_long_tip4p_long.cpp +++ b/src/KSPACE/pair_lj_long_tip4p_long.cpp @@ -1,1641 +1,1641 @@ /* ---------------------------------------------------------------------- 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: Amalie Frischknecht and Ahmed Ismail (SNL) Rolf Isele-Holder (Aachen University) ------------------------------------------------------------------------- */ #include #include #include #include #include "pair_lj_long_tip4p_long.h" #include "angle.h" #include "atom.h" #include "bond.h" #include "comm.h" #include "domain.h" #include "force.h" #include "kspace.h" #include "update.h" #include "respa.h" #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 #define A2 -0.284496736 #define A3 1.421413741 #define A4 -1.453152027 #define A5 1.061405429 /* ---------------------------------------------------------------------- */ PairLJLongTIP4PLong::PairLJLongTIP4PLong(LAMMPS *lmp) : PairLJLongCoulLong(lmp) { dispersionflag = tip4pflag = 1; single_enable = 0; respa_enable = 1; nmax = 0; hneigh = NULL; newsite = NULL; // TIP4P cannot compute virial as F dot r // due to find_M() finding bonded H atoms which are not near O atom no_virial_fdotr_compute = 1; } /* ---------------------------------------------------------------------- */ PairLJLongTIP4PLong::~PairLJLongTIP4PLong() { memory->destroy(hneigh); memory->destroy(newsite); } /* ---------------------------------------------------------------------- */ void PairLJLongTIP4PLong::compute(int eflag, int vflag) { int i,j,ii,jj,inum,jnum,itype,jtype,itable; int n,vlist[6]; int key; int iH1,iH2,jH1,jH2; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul; double fraction,table; double r,r2inv,forcecoul,forcelj,cforce; double factor_coul; double grij,expm2,prefactor,t,erfc; double fO[3],fH[3],fd[3],v[6]; double *x1,*x2,*xH1,*xH2; int *ilist,*jlist,*numneigh,**firstneigh; double rsq; evdwl = ecoul = 0.0; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; // reallocate hneigh & newsite if necessary // initialize hneigh[0] to -1 on steps when reneighboring occurred // initialize hneigh[2] to 0 every step int nlocal = atom->nlocal; int nall = nlocal + atom->nghost; if (atom->nmax > nmax) { nmax = atom->nmax; memory->destroy(hneigh); memory->create(hneigh,nmax,3,"pair:hneigh"); memory->destroy(newsite); memory->create(newsite,nmax,3,"pair:newsite"); } if (neighbor->ago == 0) for (i = 0; i < nall; i++) hneigh[i][0] = -1; for (i = 0; i < nall; i++) hneigh[i][2] = 0; double **f = atom->f; double **x = atom->x; double *q = atom->q; tagint *tag = atom->tag; int *type = atom->type; double *special_coul = force->special_coul; double *special_lj = force->special_lj; int newton_pair = force->newton_pair; double qqrd2e = force->qqrd2e; double cut_coulsqplus = (cut_coul+2.0*qdist)*(cut_coul+2.0*qdist); int order1 = ewald_order&(1<<1), order6 = ewald_order&(1<<6); int ni; double *lj1i, *lj2i, *lj3i, *lj4i, *offseti; double g2 = g_ewald_6*g_ewald_6, g6 = g2*g2*g2, g8 = g6*g2; 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]; qtmp = q[i]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; if (itype == typeO) { if (hneigh[i][0] < 0) { iH1 = atom->map(tag[i] + 1); iH2 = atom->map(tag[i] + 2); if (iH1 == -1 || iH2 == -1) error->one(FLERR,"TIP4P hydrogen is missing"); if (atom->type[iH1] != typeH || atom->type[iH2] != typeH) error->one(FLERR,"TIP4P hydrogen has incorrect atom type"); // set iH1,iH2 to closest image to O iH1 = domain->closest_image(i,iH1); iH2 = domain->closest_image(i,iH2); compute_newsite(x[i],x[iH1],x[iH2],newsite[i]); hneigh[i][0] = iH1; hneigh[i][1] = iH2; hneigh[i][2] = 1; } else { iH1 = hneigh[i][0]; iH2 = hneigh[i][1]; if (hneigh[i][2] == 0) { hneigh[i][2] = 1; compute_newsite(x[i],x[iH1],x[iH2],newsite[i]); } } x1 = newsite[i]; } else x1 = x[i]; jlist = firstneigh[i]; jnum = numneigh[i]; offseti = offset[itype]; lj1i = lj1[itype]; lj2i = lj2[itype]; lj3i = lj3[itype]; lj4i = lj4[itype]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; ni = sbmask(j); factor_coul = special_coul[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 < cut_ljsq[itype][jtype]) { // lj r2inv = 1.0/rsq; if (order6) { // long-range lj if (!ndisptablebits || rsq <= tabinnerdispsq) { register double rn = r2inv*r2inv*r2inv; register double x2 = g2*rsq, a2 = 1.0/x2; x2 = a2*exp(-x2)*lj4i[jtype]; if (ni == 0) { forcelj = (rn*=rn)*lj1i[jtype]-g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq; if (eflag) evdwl = rn*lj3i[jtype]-g6*((a2+1.0)*a2+0.5)*x2; } else { // special case register double f = special_lj[ni], t = rn*(1.0-f); forcelj = f*(rn *= rn)*lj1i[jtype]- g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq+t*lj2i[jtype]; if (eflag) evdwl = f*rn*lj3i[jtype]-g6*((a2+1.0)*a2+0.5)*x2+t*lj4i[jtype]; } } else { // table real space register union_int_float_t disp_t; disp_t.f = rsq; register const int disp_k = (disp_t.i & ndispmask)>>ndispshiftbits; register double f_disp = (rsq-rdisptable[disp_k])*drdisptable[disp_k]; register double rn = r2inv*r2inv*r2inv; if (ni == 0) { forcelj = (rn*=rn)*lj1i[jtype]-(fdisptable[disp_k]+f_disp*dfdisptable[disp_k])*lj4i[jtype]; if (eflag) evdwl = rn*lj3i[jtype]-(edisptable[disp_k]+f_disp*dedisptable[disp_k])*lj4i[jtype]; } else { // special case register double f = special_lj[ni], t = rn*(1.0-f); forcelj = f*(rn *= rn)*lj1i[jtype]-(fdisptable[disp_k]+f_disp*dfdisptable[disp_k])*lj4i[jtype]+t*lj2i[jtype]; if (eflag) evdwl = f*rn*lj3i[jtype]-(edisptable[disp_k]+f_disp*dedisptable[disp_k])*lj4i[jtype]+t*lj4i[jtype]; } } } else { // cut lj register double rn = r2inv*r2inv*r2inv; if (ni == 0) { forcelj = rn*(rn*lj1i[jtype]-lj2i[jtype]); if (eflag) evdwl = rn*(rn*lj3i[jtype]-lj4i[jtype])-offseti[jtype]; } else { // special case register double f = special_lj[ni]; forcelj = f*rn*(rn*lj1i[jtype]-lj2i[jtype]); if (eflag) evdwl = f * (rn*(rn*lj3i[jtype]-lj4i[jtype])-offseti[jtype]); } } forcelj *= r2inv; f[i][0] += delx*forcelj; f[i][1] += dely*forcelj; f[i][2] += delz*forcelj; f[j][0] -= delx*forcelj; f[j][1] -= dely*forcelj; f[j][2] -= delz*forcelj; if (evflag) ev_tally(i,j,nlocal,newton_pair, evdwl,0.0,forcelj,delx,dely,delz); } // adjust rsq and delxyz for off-site O charge(s) // ADDITIONAL REQEUST REQUIRED HERE!!!!! if (rsq < cut_coulsqplus) { if (itype == typeO || jtype == typeO) { if (jtype == typeO) { if (hneigh[j][0] < 0) { jH1 = atom->map(tag[j] + 1); jH2 = atom->map(tag[j] + 2); if (jH1 == -1 || jH2 == -1) error->one(FLERR,"TIP4P hydrogen is missing"); if (atom->type[jH1] != typeH || atom->type[jH2] != typeH) error->one(FLERR,"TIP4P hydrogen has incorrect atom type"); // set jH1,jH2 to closest image to O jH1 = domain->closest_image(j,jH1); jH2 = domain->closest_image(j,jH2); compute_newsite(x[j],x[jH1],x[jH2],newsite[j]); hneigh[j][0] = jH1; hneigh[j][1] = jH2; hneigh[j][2] = 1; } else { jH1 = hneigh[j][0]; jH2 = hneigh[j][1]; if (hneigh[j][2] == 0) { hneigh[j][2] = 1; compute_newsite(x[j],x[jH1],x[jH2],newsite[j]); } } x2 = newsite[j]; } else x2 = x[j]; delx = x1[0] - x2[0]; dely = x1[1] - x2[1]; delz = x1[2] - x2[2]; rsq = delx*delx + dely*dely + delz*delz; } // test current rsq against cutoff and compute Coulombic force if (rsq < cut_coulsq && order1) { r2inv = 1.0 / rsq; if (!ncoultablebits || rsq <= tabinnersq) { r = sqrt(rsq); grij = g_ewald * r; expm2 = exp(-grij*grij); t = 1.0 / (1.0 + EWALD_P*grij); erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; prefactor = qqrd2e * qtmp*q[j]/r; forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); if (factor_coul < 1.0) { forcecoul -= (1.0-factor_coul)*prefactor; } } else { union_int_float_t rsq_lookup; rsq_lookup.f = rsq; itable = rsq_lookup.i & ncoulmask; itable >>= ncoulshiftbits; fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable]; table = ftable[itable] + fraction*dftable[itable]; forcecoul = qtmp*q[j] * table; if (factor_coul < 1.0) { table = ctable[itable] + fraction*dctable[itable]; prefactor = qtmp*q[j] * table; forcecoul -= (1.0-factor_coul)*prefactor; } } cforce = forcecoul * r2inv; //if (evflag) ev_tally(i,j,nlocal,newton_pair, // evdwl,0.0,cforce,delx,dely,delz); // if i,j are not O atoms, force is applied directly // if i or j are O atoms, force is on fictitious atom & partitioned // force partitioning due to Feenstra, J Comp Chem, 20, 786 (1999) // f_f = fictitious force, fO = f_f (1 - 2 alpha), fH = alpha f_f // preserves total force and torque on water molecule // virial = sum(r x F) where each water's atoms are near xi and xj // vlist stores 2,4,6 atoms whose forces contribute to virial n = 0; key = 0; if (itype != typeO) { f[i][0] += delx * cforce; f[i][1] += dely * cforce; f[i][2] += delz * cforce; if (vflag) { v[0] = x[i][0] * delx * cforce; v[1] = x[i][1] * dely * cforce; v[2] = x[i][2] * delz * cforce; v[3] = x[i][0] * dely * cforce; v[4] = x[i][0] * delz * cforce; v[5] = x[i][1] * delz * cforce; } vlist[n++] = i; } else { key += 1; fd[0] = delx*cforce; fd[1] = dely*cforce; fd[2] = delz*cforce; fO[0] = fd[0]*(1 - alpha); fO[1] = fd[1]*(1 - alpha); fO[2] = fd[2]*(1 - alpha); fH[0] = 0.5 * alpha * fd[0]; fH[1] = 0.5 * alpha * fd[1]; fH[2] = 0.5 * alpha * fd[2]; f[i][0] += fO[0]; f[i][1] += fO[1]; f[i][2] += fO[2]; f[iH1][0] += fH[0]; f[iH1][1] += fH[1]; f[iH1][2] += fH[2]; f[iH2][0] += fH[0]; f[iH2][1] += fH[1]; f[iH2][2] += fH[2]; if (vflag) { xH1 = x[iH1]; xH2 = x[iH2]; v[0] = x[i][0]*fO[0] + xH1[0]*fH[0] + xH2[0]*fH[0]; v[1] = x[i][1]*fO[1] + xH1[1]*fH[1] + xH2[1]*fH[1]; v[2] = x[i][2]*fO[2] + xH1[2]*fH[2] + xH2[2]*fH[2]; v[3] = x[i][0]*fO[1] + xH1[0]*fH[1] + xH2[0]*fH[1]; v[4] = x[i][0]*fO[2] + xH1[0]*fH[2] + xH2[0]*fH[2]; v[5] = x[i][1]*fO[2] + xH1[1]*fH[2] + xH2[1]*fH[2]; } vlist[n++] = i; vlist[n++] = iH1; vlist[n++] = iH2; } if (jtype != typeO) { f[j][0] -= delx * cforce; f[j][1] -= dely * cforce; f[j][2] -= delz * cforce; if (vflag) { v[0] -= x[j][0] * delx * cforce; v[1] -= x[j][1] * dely * cforce; v[2] -= x[j][2] * delz * cforce; v[3] -= x[j][0] * dely * cforce; v[4] -= x[j][0] * delz * cforce; v[5] -= x[j][1] * delz * cforce; } vlist[n++] = j; } else { key += 2; fd[0] = -delx*cforce; fd[1] = -dely*cforce; fd[2] = -delz*cforce; fO[0] = fd[0]*(1 - alpha); fO[1] = fd[1]*(1 - alpha); fO[2] = fd[2]*(1 - alpha); fH[0] = 0.5 * alpha * fd[0]; fH[1] = 0.5 * alpha * fd[1]; fH[2] = 0.5 * alpha * fd[2]; f[j][0] += fO[0]; f[j][1] += fO[1]; f[j][2] += fO[2]; f[jH1][0] += fH[0]; f[jH1][1] += fH[1]; f[jH1][2] += fH[2]; f[jH2][0] += fH[0]; f[jH2][1] += fH[1]; f[jH2][2] += fH[2]; if (vflag) { xH1 = x[jH1]; xH2 = x[jH2]; v[0] += x[j][0]*fO[0] + xH1[0]*fH[0] + xH2[0]*fH[0]; v[1] += x[j][1]*fO[1] + xH1[1]*fH[1] + xH2[1]*fH[1]; v[2] += x[j][2]*fO[2] + xH1[2]*fH[2] + xH2[2]*fH[2]; v[3] += x[j][0]*fO[1] + xH1[0]*fH[1] + xH2[0]*fH[1]; v[4] += x[j][0]*fO[2] + xH1[0]*fH[2] + xH2[0]*fH[2]; v[5] += x[j][1]*fO[2] + xH1[1]*fH[2] + xH2[1]*fH[2]; } vlist[n++] = j; vlist[n++] = jH1; vlist[n++] = jH2; } if (eflag) { if (!ncoultablebits || rsq <= tabinnersq) ecoul = prefactor*erfc; else { table = etable[itable] + fraction*detable[itable]; ecoul = qtmp*q[j] * table; } if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor; } else ecoul = 0.0; if (evflag) ev_tally_tip4p(key,vlist,v,ecoul,alpha); } } } } } /* --------------------------------------------------------------------- */ void PairLJLongTIP4PLong::compute_inner() { int i,j,ii,jj,inum,jnum,itype,jtype; int iH1,iH2,jH1,jH2; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; double r2inv,forcecoul,forcelj,cforce; double fO[3],fH[3],fd[3]; double *x1,*x2; int *ilist,*jlist,*numneigh,**firstneigh; double rsq, qri; double cut_out_on = cut_respa[0]; double cut_out_off = cut_respa[1]; double cut_out_diff = cut_out_off - cut_out_on; double cut_out_on_sq = cut_out_on*cut_out_on; double cut_out_off_sq = cut_out_off*cut_out_off; // reallocate hneigh & newsite if necessary // initialize hneigh[0] to -1 on steps when reneighboring occurred // initialize hneigh[2] to 0 every step int nlocal = atom->nlocal; int nall = nlocal + atom->nghost; // atom->nmax > nmax will occur during setup if (atom->nmax > nmax) { nmax = atom->nmax; memory->destroy(hneigh); memory->create(hneigh,nmax,3,"pair:hneigh"); memory->destroy(newsite); memory->create(newsite,nmax,3,"pair:newsite"); } if (neighbor->ago == 0) for (i = 0; i < nall; i++) hneigh[i][0] = -1; for (i = 0; i < nall; i++) hneigh[i][2] = 0; double **f = atom->f; double **x = atom->x; double *q = atom->q; tagint *tag = atom->tag; int *type = atom->type; double *special_coul = force->special_coul; double *special_lj = force->special_lj; double qqrd2e = force->qqrd2e; double cut_coulsqplus = (cut_coul+2.0*qdist)*(cut_coul+2.0*qdist); int order1 = ewald_order&(1<<1); int ni; double *lj1i, *lj2i; inum = listinner->inum; ilist = listinner->ilist; numneigh = listinner->numneigh; firstneigh = listinner->firstneigh; // loop over neighbors of my atoms for (ii = 0; ii < inum; ii++) { i = ilist[ii]; qtmp = q[i]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; if (itype == typeO && order1) { if (hneigh[i][0] < 0) { iH1 = atom->map(tag[i] + 1); iH2 = atom->map(tag[i] + 2); if (iH1 == -1 || iH2 == -1) error->one(FLERR,"TIP4P hydrogen is missing"); if (atom->type[iH1] != typeH || atom->type[iH2] != typeH) error->one(FLERR,"TIP4P hydrogen has incorrect atom type"); // set iH1,iH2 to closest image to O iH1 = domain->closest_image(i,iH1); iH2 = domain->closest_image(i,iH2); compute_newsite(x[i],x[iH1],x[iH2],newsite[i]); hneigh[i][0] = iH1; hneigh[i][1] = iH2; hneigh[i][2] = 1; } else { iH1 = hneigh[i][0]; iH2 = hneigh[i][1]; if (hneigh[i][2] == 0) { hneigh[i][2] = 1; compute_newsite(x[i],x[iH1],x[iH2],newsite[i]); } } x1 = newsite[i]; } else x1 = x[i]; jlist = firstneigh[i]; jnum = numneigh[i]; lj1i = lj1[itype]; lj2i = lj2[itype]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; ni = 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 < cut_ljsq[itype][jtype] && rsq < cut_out_off_sq ) { // lj r2inv = 1.0/rsq; register double rn = r2inv*r2inv*r2inv; if (ni == 0) forcelj = rn*(rn*lj1i[jtype]-lj2i[jtype]); else { // special case register double f = special_lj[ni]; forcelj = f*rn*(rn*lj1i[jtype]-lj2i[jtype]); } if (rsq > cut_out_on_sq) { // switching register double rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff; forcelj *= 1.0 + rsw*rsw*(2.0*rsw-3.0); } forcelj *= r2inv; f[i][0] += delx*forcelj; f[i][1] += dely*forcelj; f[i][2] += delz*forcelj; f[j][0] -= delx*forcelj; f[j][1] -= dely*forcelj; f[j][2] -= delz*forcelj; } // adjust rsq and delxyz for off-site O charge(s) // ADDITIONAL REQEUST REQUIRED HERE!!!!! if (rsq < cut_coulsqplus && order1) { if (itype == typeO || jtype == typeO) { if (jtype == typeO) { if (hneigh[j][0] < 0) { jH1 = atom->map(tag[j] + 1); jH2 = atom->map(tag[j] + 2); if (jH1 == -1 || jH2 == -1) error->one(FLERR,"TIP4P hydrogen is missing"); if (atom->type[jH1] != typeH || atom->type[jH2] != typeH) error->one(FLERR,"TIP4P hydrogen has incorrect atom type"); // set jH1,jH2 to closest image to O jH1 = domain->closest_image(j,jH1); jH2 = domain->closest_image(j,jH2); compute_newsite(x[j],x[jH1],x[jH2],newsite[j]); hneigh[j][0] = jH1; hneigh[j][1] = jH2; hneigh[j][2] = 1; } else { jH1 = hneigh[j][0]; jH2 = hneigh[j][1]; if (hneigh[j][2] == 0) { hneigh[j][2] = 1; compute_newsite(x[j],x[jH1],x[jH2],newsite[j]); } } x2 = newsite[j]; } else x2 = x[j]; delx = x1[0] - x2[0]; dely = x1[1] - x2[1]; delz = x1[2] - x2[2]; rsq = delx*delx + dely*dely + delz*delz; } // test current rsq against cutoff and compute Coulombic force if (rsq < cut_coulsq && rsq < cut_out_off_sq) { r2inv = 1.0 / rsq; qri = qqrd2e*qtmp; if (ni == 0) forcecoul = qri*q[j]*sqrt(r2inv); else { forcecoul = qri*q[j]*sqrt(r2inv)*special_coul[ni]; } if (rsq > cut_out_on_sq) { // switching register double rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff; forcecoul *= 1.0 + rsw*rsw*(2.0*rsw-3.0); } cforce = forcecoul * r2inv; //if (evflag) ev_tally(i,j,nlocal,newton_pair, // evdwl,0.0,cforce,delx,dely,delz); // if i,j are not O atoms, force is applied directly // if i or j are O atoms, force is on fictitious atom & partitioned // force partitioning due to Feenstra, J Comp Chem, 20, 786 (1999) // f_f = fictitious force, fO = f_f (1 - 2 alpha), fH = alpha f_f // preserves total force and torque on water molecule // virial = sum(r x F) where each water's atoms are near xi and xj // vlist stores 2,4,6 atoms whose forces contribute to virial if (itype != typeO) { f[i][0] += delx * cforce; f[i][1] += dely * cforce; f[i][2] += delz * cforce; } else { fd[0] = delx*cforce; fd[1] = dely*cforce; fd[2] = delz*cforce; fO[0] = fd[0]*(1 - alpha); fO[1] = fd[1]*(1 - alpha); fO[2] = fd[2]*(1 - alpha); fH[0] = 0.5 * alpha * fd[0]; fH[1] = 0.5 * alpha * fd[1]; fH[2] = 0.5 * alpha * fd[2]; f[i][0] += fO[0]; f[i][1] += fO[1]; f[i][2] += fO[2]; f[iH1][0] += fH[0]; f[iH1][1] += fH[1]; f[iH1][2] += fH[2]; f[iH2][0] += fH[0]; f[iH2][1] += fH[1]; f[iH2][2] += fH[2]; } if (jtype != typeO) { f[j][0] -= delx * cforce; f[j][1] -= dely * cforce; f[j][2] -= delz * cforce; } else { fd[0] = -delx*cforce; fd[1] = -dely*cforce; fd[2] = -delz*cforce; fO[0] = fd[0]*(1 - alpha); fO[1] = fd[1]*(1 - alpha); fO[2] = fd[2]*(1 - alpha); fH[0] = 0.5 * alpha * fd[0]; fH[1] = 0.5 * alpha * fd[1]; fH[2] = 0.5 * alpha * fd[2]; f[j][0] += fO[0]; f[j][1] += fO[1]; f[j][2] += fO[2]; f[jH1][0] += fH[0]; f[jH1][1] += fH[1]; f[jH1][2] += fH[2]; f[jH2][0] += fH[0]; f[jH2][1] += fH[1]; f[jH2][2] += fH[2]; } } } } } } /* --------------------------------------------------------------------- */ void PairLJLongTIP4PLong::compute_middle() { int i,j,ii,jj,inum,jnum,itype,jtype; int iH1,iH2,jH1,jH2; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; double r2inv,forcecoul,forcelj,cforce; double fO[3],fH[3],fd[3]; double *x1,*x2; int *ilist,*jlist,*numneigh,**firstneigh; double rsq,qri; double cut_in_off = cut_respa[0]; double cut_in_on = cut_respa[1]; double cut_out_on = cut_respa[2]; double cut_out_off = cut_respa[3]; double cut_in_diff = cut_in_on - cut_in_off; double cut_out_diff = cut_out_off - cut_out_on; double cut_in_off_sq = cut_in_off*cut_in_off; double cut_in_on_sq = cut_in_on*cut_in_on; double cut_out_on_sq = cut_out_on*cut_out_on; double cut_out_off_sq = cut_out_off*cut_out_off; // reallocate hneigh & newsite if necessary // initialize hneigh[0] to -1 on steps when reneighboring occurred // initialize hneigh[2] to 0 every step double **f = atom->f; double **x = atom->x; double *q = atom->q; tagint *tag = atom->tag; int *type = atom->type; double *special_coul = force->special_coul; double *special_lj = force->special_lj; double qqrd2e = force->qqrd2e; double cut_coulsqplus = (cut_coul+2.0*qdist)*(cut_coul+2.0*qdist); int order1 = ewald_order&(1<<1); int ni; double *lj1i, *lj2i; inum = listmiddle->inum; ilist = listmiddle->ilist; numneigh = listmiddle->numneigh; firstneigh = listmiddle->firstneigh; // loop over neighbors of my atoms for (ii = 0; ii < inum; ii++) { i = ilist[ii]; qtmp = q[i]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; if (itype == typeO && order1) { if (hneigh[i][0] < 0) { iH1 = atom->map(tag[i] + 1); iH2 = atom->map(tag[i] + 2); if (iH1 == -1 || iH2 == -1) error->one(FLERR,"TIP4P hydrogen is missing"); if (atom->type[iH1] != typeH || atom->type[iH2] != typeH) error->one(FLERR,"TIP4P hydrogen has incorrect atom type"); // set iH1,iH2 to closest image to O iH1 = domain->closest_image(i,iH1); iH2 = domain->closest_image(i,iH2); compute_newsite(x[i],x[iH1],x[iH2],newsite[i]); hneigh[i][0] = iH1; hneigh[i][1] = iH2; hneigh[i][2] = 1; } else { iH1 = hneigh[i][0]; iH2 = hneigh[i][1]; if (hneigh[i][2] == 0) { hneigh[i][2] = 1; compute_newsite(x[i],x[iH1],x[iH2],newsite[i]); } } x1 = newsite[i]; } else x1 = x[i]; jlist = firstneigh[i]; jnum = numneigh[i]; lj1i = lj1[itype]; lj2i = lj2[itype]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; ni = 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 < cut_ljsq[itype][jtype] && rsq >= cut_in_off_sq && rsq <= cut_out_off_sq ) { // lj r2inv = 1.0/rsq; register double rn = r2inv*r2inv*r2inv; if (ni == 0) forcelj = rn*(rn*lj1i[jtype]-lj2i[jtype]); else { // special case register double f = special_lj[ni]; forcelj = f*rn*(rn*lj1i[jtype]-lj2i[jtype]); } if (rsq < cut_in_on_sq) { // switching register double rsw = (sqrt(rsq) - cut_in_off)/cut_in_diff; forcelj *= rsw*rsw*(3.0 - 2.0*rsw); } if (rsq > cut_out_on_sq) { register double rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff; forcelj *= 1.0 + rsw*rsw*(2.0*rsw-3.0); } forcelj *= r2inv; f[i][0] += delx*forcelj; f[i][1] += dely*forcelj; f[i][2] += delz*forcelj; f[j][0] -= delx*forcelj; f[j][1] -= dely*forcelj; f[j][2] -= delz*forcelj; } // adjust rsq and delxyz for off-site O charge(s) // ADDITIONAL REQEUST REQUIRED HERE!!!!! if (rsq < cut_coulsqplus && order1) { if (itype == typeO || jtype == typeO) { if (jtype == typeO) { if (hneigh[j][0] < 0) { jH1 = atom->map(tag[j] + 1); jH2 = atom->map(tag[j] + 2); if (jH1 == -1 || jH2 == -1) error->one(FLERR,"TIP4P hydrogen is missing"); if (atom->type[jH1] != typeH || atom->type[jH2] != typeH) error->one(FLERR,"TIP4P hydrogen has incorrect atom type"); // set jH1,jH2 to closest image to O jH1 = domain->closest_image(j,jH1); jH2 = domain->closest_image(j,jH2); compute_newsite(x[j],x[jH1],x[jH2],newsite[j]); hneigh[j][0] = jH1; hneigh[j][1] = jH2; hneigh[j][2] = 1; } else { jH1 = hneigh[j][0]; jH2 = hneigh[j][1]; if (hneigh[j][2] == 0) { hneigh[j][2] = 1; compute_newsite(x[j],x[jH1],x[jH2],newsite[j]); } } x2 = newsite[j]; } else x2 = x[j]; delx = x1[0] - x2[0]; dely = x1[1] - x2[1]; delz = x1[2] - x2[2]; rsq = delx*delx + dely*dely + delz*delz; } // test current rsq against cutoff and compute Coulombic force if (rsq < cut_coulsq && rsq >= cut_in_off_sq && rsq <= cut_out_off_sq) { r2inv = 1.0 / rsq; qri = qqrd2e*qtmp; if (ni == 0) forcecoul = qri*q[j]*sqrt(r2inv); else { forcecoul = qri*q[j]*sqrt(r2inv)*special_coul[ni]; } if (rsq < cut_in_on_sq) { // switching register double rsw = (sqrt(rsq) - cut_in_off)/cut_in_diff; forcecoul *= rsw*rsw*(3.0 - 2.0*rsw); } if (rsq > cut_out_on_sq) { register double rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff; forcecoul *= 1.0 + rsw*rsw*(2.0*rsw-3.0); } cforce = forcecoul * r2inv; //if (evflag) ev_tally(i,j,nlocal,newton_pair, // evdwl,0.0,cforce,delx,dely,delz); // if i,j are not O atoms, force is applied directly // if i or j are O atoms, force is on fictitious atom & partitioned // force partitioning due to Feenstra, J Comp Chem, 20, 786 (1999) // f_f = fictitious force, fO = f_f (1 - 2 alpha), fH = alpha f_f // preserves total force and torque on water molecule // virial = sum(r x F) where each water's atoms are near xi and xj // vlist stores 2,4,6 atoms whose forces contribute to virial if (itype != typeO) { f[i][0] += delx * cforce; f[i][1] += dely * cforce; f[i][2] += delz * cforce; } else { fd[0] = delx*cforce; fd[1] = dely*cforce; fd[2] = delz*cforce; fO[0] = fd[0]*(1 - alpha); fO[1] = fd[1]*(1 - alpha); fO[2] = fd[2]*(1 - alpha); fH[0] = 0.5 * alpha * fd[0]; fH[1] = 0.5 * alpha * fd[1]; fH[2] = 0.5 * alpha * fd[2]; f[i][0] += fO[0]; f[i][1] += fO[1]; f[i][2] += fO[2]; f[iH1][0] += fH[0]; f[iH1][1] += fH[1]; f[iH1][2] += fH[2]; f[iH2][0] += fH[0]; f[iH2][1] += fH[1]; f[iH2][2] += fH[2]; } if (jtype != typeO) { f[j][0] -= delx * cforce; f[j][1] -= dely * cforce; f[j][2] -= delz * cforce; } else { fd[0] = -delx*cforce; fd[1] = -dely*cforce; fd[2] = -delz*cforce; fO[0] = fd[0]*(1 - alpha); fO[1] = fd[1]*(1 - alpha); fO[2] = fd[2]*(1 - alpha); fH[0] = 0.5 * alpha * fd[0]; fH[1] = 0.5 * alpha * fd[1]; fH[2] = 0.5 * alpha * fd[2]; f[j][0] += fO[0]; f[j][1] += fO[1]; f[j][2] += fO[2]; f[jH1][0] += fH[0]; f[jH1][1] += fH[1]; f[jH1][2] += fH[2]; f[jH2][0] += fH[0]; f[jH2][1] += fH[1]; f[jH2][2] += fH[2]; } } } } } } /* --------------------------------------------------------------------- */ void PairLJLongTIP4PLong::compute_outer(int eflag, int vflag) { int i,j,ii,jj,inum,jnum,itype,jtype; int n,vlist[6]; int key; int iH1,iH2,jH1,jH2; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul; double r2inv,forcecoul,forcelj,cforce, respa_coul, respa_lj, frespa,fvirial; double fO[3],fH[3],fd[3],v[6]; double *x1,*x2,*xH1,*xH2; int *ilist,*jlist,*numneigh,**firstneigh; double rsq,qri; int respa_flag; evdwl = ecoul = 0.0; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; // reallocate hneigh & newsite if necessary // initialize hneigh[0] to -1 on steps when reneighboring occurred // initialize hneigh[2] to 0 every step int nlocal = atom->nlocal; int nall = nlocal + atom->nghost; if (atom->nmax > nmax) { nmax = atom->nmax; memory->destroy(hneigh); memory->create(hneigh,nmax,3,"pair:hneigh"); memory->destroy(newsite); memory->create(newsite,nmax,3,"pair:newsite"); } if (neighbor->ago == 0) { for (i = 0; i < nall; i++) hneigh[i][0] = -1; for (i = 0; i < nall; i++) hneigh[i][2] = 0; } double **f = atom->f; double **x = atom->x; double *q = atom->q; tagint *tag = atom->tag; int *type = atom->type; double *special_coul = force->special_coul; double *special_lj = force->special_lj; int newton_pair = force->newton_pair; double qqrd2e = force->qqrd2e; double cut_coulsqplus = (cut_coul+2.0*qdist)*(cut_coul+2.0*qdist); int order1 = ewald_order&(1<<1), order6 = ewald_order&(1<<6); int ni; double *lj1i, *lj2i, *lj3i, *lj4i, *offseti; double g2 = g_ewald_6*g_ewald_6, g6 = g2*g2*g2, g8 = g6*g2; double cut_in_off = cut_respa[2]; double cut_in_on = cut_respa[3]; double cut_in_diff = cut_in_on - cut_in_off; double cut_in_off_sq = cut_in_off*cut_in_off; double cut_in_on_sq = cut_in_on*cut_in_on; inum = listouter->inum; ilist = listouter->ilist; numneigh = listouter->numneigh; firstneigh = listouter->firstneigh; // loop over neighbors of my atoms for (ii = 0; ii < inum; ii++) { i = ilist[ii]; qtmp = q[i]; qri = qtmp*qqrd2e; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; if (itype == typeO) { if (hneigh[i][0] < 0) { iH1 = atom->map(tag[i] + 1); iH2 = atom->map(tag[i] + 2); if (iH1 == -1 || iH2 == -1) error->one(FLERR,"TIP4P hydrogen is missing"); if (atom->type[iH1] != typeH || atom->type[iH2] != typeH) error->one(FLERR,"TIP4P hydrogen has incorrect atom type"); // set iH1,iH2 to closest image to O iH1 = domain->closest_image(i,iH1); iH2 = domain->closest_image(i,iH2); compute_newsite(x[i],x[iH1],x[iH2],newsite[i]); hneigh[i][0] = iH1; hneigh[i][1] = iH2; hneigh[i][2] = 1; } else { iH1 = hneigh[i][0]; iH2 = hneigh[i][1]; if (hneigh[i][2] == 0) { hneigh[i][2] = 1; compute_newsite(x[i],x[iH1],x[iH2],newsite[i]); } } x1 = newsite[i]; } else x1 = x[i]; jlist = firstneigh[i]; jnum = numneigh[i]; offseti = offset[itype]; lj1i = lj1[itype]; lj2i = lj2[itype]; lj3i = lj3[itype]; lj4i = lj4[itype]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; ni = 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]; respa_coul = 0; respa_lj = 0; if (rsq < cut_ljsq[itype][jtype]) { // lj frespa = 1.0; // check whether and how to compute respa corrections respa_flag = rsq < cut_in_on_sq ? 1 : 0; if (respa_flag && (rsq > cut_in_off_sq)) { register double rsw = (sqrt(rsq)-cut_in_off)/cut_in_diff; frespa = 1-rsw*rsw*(3.0-2.0*rsw); } r2inv = 1.0/rsq; register double rn = r2inv*r2inv*r2inv; if (respa_flag) respa_lj = ni == 0 ? // correct for respa frespa*rn*(rn*lj1i[jtype]-lj2i[jtype]) : frespa*rn*(rn*lj1i[jtype]-lj2i[jtype])*special_lj[ni]; if (order6) { // long-range form if (!ndisptablebits || rsq <= tabinnerdispsq) { register double x2 = g2*rsq, a2 = 1.0/x2; x2 = a2*exp(-x2)*lj4i[jtype]; if (ni == 0) { forcelj = (rn*=rn)*lj1i[jtype]-g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq-respa_lj; if (eflag) evdwl = rn*lj3i[jtype]-g6*((a2+1.0)*a2+0.5)*x2; } else { // correct for special register double f = special_lj[ni], t = rn*(1.0-f); forcelj = f*(rn *= rn)*lj1i[jtype]- g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq+t*lj2i[jtype]-respa_lj; if (eflag) evdwl = f*rn*lj3i[jtype]-g6*((a2+1.0)*a2+0.5)*x2+t*lj4i[jtype]; } } else { // table real space register union_int_float_t disp_t; disp_t.f = rsq; register const int disp_k = (disp_t.i & ndispmask)>>ndispshiftbits; register double f_disp = (rsq-rdisptable[disp_k])*drdisptable[disp_k]; if (ni == 0) { forcelj = (rn*=rn)*lj1i[jtype]-(fdisptable[disp_k]+f_disp*dfdisptable[disp_k])*lj4i[jtype]-respa_lj; if (eflag) evdwl = rn*lj3i[jtype]-(edisptable[disp_k]+f_disp*dedisptable[disp_k])*lj4i[jtype]; } else { // special case register double f = special_lj[ni], t = rn*(1.0-f); forcelj = f*(rn *= rn)*lj1i[jtype]-(fdisptable[disp_k]+f_disp*dfdisptable[disp_k])*lj4i[jtype]+t*lj2i[jtype]-respa_lj; if (eflag) evdwl = f*rn*lj3i[jtype]-(edisptable[disp_k]+f_disp*dedisptable[disp_k])*lj4i[jtype]+t*lj4i[jtype]; } } } else { // cut form if (ni == 0) { forcelj = rn*(rn*lj1i[jtype]-lj2i[jtype])-respa_lj; if (eflag) evdwl = rn*(rn*lj3i[jtype]-lj4i[jtype])-offseti[jtype]; } else { // correct for special register double f = special_lj[ni]; forcelj = f*rn*(rn*lj1i[jtype]-lj2i[jtype])-respa_lj; if (eflag) evdwl = f*(rn*(rn*lj3i[jtype]-lj4i[jtype])-offseti[jtype]); } } forcelj *= r2inv; f[i][0] += delx*forcelj; f[i][1] += dely*forcelj; f[i][2] += delz*forcelj; f[j][0] -= delx*forcelj; f[j][1] -= dely*forcelj; f[j][2] -= delz*forcelj; if (evflag) { fvirial = forcelj + respa_lj*r2inv; ev_tally(i,j,nlocal,newton_pair, evdwl,0.0,fvirial,delx,dely,delz); } } // adjust rsq and delxyz for off-site O charge(s) // ADDITIONAL REQEUST REQUIRED HERE!!!!! if (rsq < cut_coulsqplus) { if (itype == typeO || jtype == typeO) { if (jtype == typeO) { if (hneigh[j][0] < 0) { jH1 = atom->map(tag[j] + 1); jH2 = atom->map(tag[j] + 2); if (jH1 == -1 || jH2 == -1) error->one(FLERR,"TIP4P hydrogen is missing"); if (atom->type[jH1] != typeH || atom->type[jH2] != typeH) error->one(FLERR,"TIP4P hydrogen has incorrect atom type"); // set jH1,jH2 to closest image to O jH1 = domain->closest_image(j,jH1); jH2 = domain->closest_image(j,jH2); compute_newsite(x[j],x[jH1],x[jH2],newsite[j]); hneigh[j][0] = jH1; hneigh[j][1] = jH2; hneigh[j][2] = 1; } else { jH1 = hneigh[j][0]; jH2 = hneigh[j][1]; if (hneigh[j][2] == 0) { hneigh[j][2] = 1; compute_newsite(x[j],x[jH1],x[jH2],newsite[j]); } } x2 = newsite[j]; } else x2 = x[j]; delx = x1[0] - x2[0]; dely = x1[1] - x2[1]; delz = x1[2] - x2[2]; rsq = delx*delx + dely*dely + delz*delz; } // test current rsq against cutoff and compute Coulombic force if ((rsq < cut_coulsq) && order1) { frespa = 1.0; // check whether and how to compute respa corrections respa_flag = rsq < cut_in_on_sq ? 1 : 0; if (respa_flag && (rsq > cut_in_off_sq)) { register double rsw = (sqrt(rsq)-cut_in_off)/cut_in_diff; frespa = 1-rsw*rsw*(3.0-2.0*rsw); } r2inv = 1.0 / rsq; if (!ncoultablebits || rsq <= tabinnersq) { // series real space register double r = sqrt(rsq), s = qri*q[j]; if (respa_flag) // correct for respa respa_coul = ni == 0 ? frespa*s/r : frespa*s/r*special_coul[ni]; register double x = g_ewald*r, t = 1.0/(1.0+EWALD_P*x); if (ni == 0) { s *= g_ewald*exp(-x*x); forcecoul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s-respa_coul; if (eflag) ecoul = t; } else { // correct for special r = s*(1.0-special_coul[ni])/r; s *= g_ewald*exp(-x*x); forcecoul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s-r-respa_coul; if (eflag) ecoul = t-r; } } // table real space else { if (respa_flag) { register double r = sqrt(rsq), s = qri*q[j]; respa_coul = ni == 0 ? frespa*s/r : frespa*s/r*special_coul[ni]; } register union_int_float_t t; t.f = rsq; register const int k = (t.i & ncoulmask) >> ncoulshiftbits; register double f = (t.f-rtable[k])*drtable[k], qiqj = qtmp*q[j]; if (ni == 0) { forcecoul = qiqj*(ftable[k]+f*dftable[k]); if (eflag) ecoul = qiqj*(etable[k]+f*detable[k]); } else { // correct for special t.f = (1.0-special_coul[ni])*(ctable[k]+f*dctable[k]); forcecoul = qiqj*(ftable[k]+f*dftable[k]-t.f); if (eflag) { t.f = (1.0-special_coul[ni])*(ptable[k]+f*dptable[k]); ecoul = qiqj*(etable[k]+f*detable[k]-t.f); } } } cforce = forcecoul * r2inv; fvirial = (forcecoul + respa_coul) * r2inv; // if i,j are not O atoms, force is applied directly // if i or j are O atoms, force is on fictitious atom & partitioned // force partitioning due to Feenstra, J Comp Chem, 20, 786 (1999) // f_f = fictitious force, fO = f_f (1 - 2 alpha), fH = alpha f_f // preserves total force and torque on water molecule // virial = sum(r x F) where each water's atoms are near xi and xj // vlist stores 2,4,6 atoms whose forces contribute to virial n = 0; key = 0; if (itype != typeO) { f[i][0] += delx * cforce; f[i][1] += dely * cforce; f[i][2] += delz * cforce; if (vflag) { v[0] = x[i][0] * delx * fvirial; v[1] = x[i][1] * dely * fvirial; v[2] = x[i][2] * delz * fvirial; v[3] = x[i][0] * dely * fvirial; v[4] = x[i][0] * delz * fvirial; v[5] = x[i][1] * delz * fvirial; } vlist[n++] = i; } else { key += 1; fd[0] = delx*cforce; fd[1] = dely*cforce; fd[2] = delz*cforce; fO[0] = fd[0]*(1 - alpha); fO[1] = fd[1]*(1 - alpha); fO[2] = fd[2]*(1 - alpha); fH[0] = 0.5 * alpha * fd[0]; fH[1] = 0.5 * alpha * fd[1]; fH[2] = 0.5 * alpha * fd[2]; f[i][0] += fO[0]; f[i][1] += fO[1]; f[i][2] += fO[2]; f[iH1][0] += fH[0]; f[iH1][1] += fH[1]; f[iH1][2] += fH[2]; f[iH2][0] += fH[0]; f[iH2][1] += fH[1]; f[iH2][2] += fH[2]; if (vflag) { fd[0] = delx*fvirial; fd[1] = dely*fvirial; fd[2] = delz*fvirial; fO[0] = fd[0]*(1 - alpha); fO[1] = fd[1]*(1 - alpha); fO[2] = fd[2]*(1 - alpha); fH[0] = 0.5 * alpha * fd[0]; fH[1] = 0.5 * alpha * fd[1]; fH[2] = 0.5 * alpha * fd[2]; - xH1 = x[jH1]; - xH2 = x[jH2]; + xH1 = x[iH1]; + xH2 = x[iH2]; v[0] = x[i][0]*fO[0] + xH1[0]*fH[0] + xH2[0]*fH[0]; v[1] = x[i][1]*fO[1] + xH1[1]*fH[1] + xH2[1]*fH[1]; v[2] = x[i][2]*fO[2] + xH1[2]*fH[2] + xH2[2]*fH[2]; v[3] = x[i][0]*fO[1] + xH1[0]*fH[1] + xH2[0]*fH[1]; v[4] = x[i][0]*fO[2] + xH1[0]*fH[2] + xH2[0]*fH[2]; v[5] = x[i][1]*fO[2] + xH1[1]*fH[2] + xH2[1]*fH[2]; } vlist[n++] = i; vlist[n++] = iH1; vlist[n++] = iH2; } if (jtype != typeO) { f[j][0] -= delx * cforce; f[j][1] -= dely * cforce; f[j][2] -= delz * cforce; if (vflag) { v[0] -= x[j][0] * delx * fvirial; v[1] -= x[j][1] * dely * fvirial; v[2] -= x[j][2] * delz * fvirial; v[3] -= x[j][0] * dely * fvirial; v[4] -= x[j][0] * delz * fvirial; v[5] -= x[j][1] * delz * fvirial; } vlist[n++] = j; } else { key += 2; fd[0] = -delx*cforce; fd[1] = -dely*cforce; fd[2] = -delz*cforce; fO[0] = fd[0]*(1 - alpha); fO[1] = fd[1]*(1 - alpha); fO[2] = fd[2]*(1 - alpha); fH[0] = 0.5 * alpha * fd[0]; fH[1] = 0.5 * alpha * fd[1]; fH[2] = 0.5 * alpha * fd[2]; f[j][0] += fO[0]; f[j][1] += fO[1]; f[j][2] += fO[2]; f[jH1][0] += fH[0]; f[jH1][1] += fH[1]; f[jH1][2] += fH[2]; f[jH2][0] += fH[0]; f[jH2][1] += fH[1]; f[jH2][2] += fH[2]; if (vflag) { fd[0] = -delx*fvirial; fd[1] = -dely*fvirial; fd[2] = -delz*fvirial; fO[0] = fd[0]*(1 - alpha); fO[1] = fd[1]*(1 - alpha); fO[2] = fd[2]*(1 - alpha); fH[0] = 0.5 * alpha * fd[0]; fH[1] = 0.5 * alpha * fd[1]; fH[2] = 0.5 * alpha * fd[2]; xH1 = x[jH1]; xH2 = x[jH2]; v[0] += x[j][0]*fO[0] + xH1[0]*fH[0] + xH2[0]*fH[0]; v[1] += x[j][1]*fO[1] + xH1[1]*fH[1] + xH2[1]*fH[1]; v[2] += x[j][2]*fO[2] + xH1[2]*fH[2] + xH2[2]*fH[2]; v[3] += x[j][0]*fO[1] + xH1[0]*fH[1] + xH2[0]*fH[1]; v[4] += x[j][0]*fO[2] + xH1[0]*fH[2] + xH2[0]*fH[2]; v[5] += x[j][1]*fO[2] + xH1[1]*fH[2] + xH2[1]*fH[2]; } vlist[n++] = j; vlist[n++] = jH1; vlist[n++] = jH2; } if (evflag) ev_tally_tip4p(key,vlist,v,ecoul,alpha); } } } } } /* ---------------------------------------------------------------------- global settings ------------------------------------------------------------------------- */ void PairLJLongTIP4PLong::settings(int narg, char **arg) { if (narg < 8 || narg > 9) error->all(FLERR,"Illegal pair_style command"); ewald_off = 0; ewald_order = 0; options(arg, 6); options(++arg, 1); if (!comm->me && ewald_order&(1<<6)) error->warning(FLERR,"Mixing forced for lj coefficients"); if (!comm->me && ewald_order==((1<<1)|(1<<6))) error->warning(FLERR, "Using largest cutoff for pair_style lj/long/tip4p/long"); if (!((ewald_order^ewald_off)&(1<<1))) error->all(FLERR, "Coulomb cut not supported in pair_style lj/long/tip4p/long"); typeO = force->inumeric(FLERR,arg[1]); typeH = force->inumeric(FLERR,arg[2]); typeB = force->inumeric(FLERR,arg[3]); typeA = force->inumeric(FLERR,arg[4]); qdist = force->numeric(FLERR,arg[5]); cut_lj_global = force->numeric(FLERR,arg[6]); if (narg == 8) cut_coul = cut_lj_global; else cut_coul = force->numeric(FLERR,arg[7]); // reset cutoffs that have been explicitly set if (allocated) { int i,j; for (i = 1; i <= atom->ntypes; i++) for (j = i; j <= atom->ntypes; j++) if (setflag[i][j]) cut_lj[i][j] = cut_lj_global; } } /* ---------------------------------------------------------------------- init specific to this pair style ------------------------------------------------------------------------- */ void PairLJLongTIP4PLong::init_style() { if (atom->tag_enable == 0) error->all(FLERR,"Pair style lj/long/tip4p/long requires atom IDs"); if (!force->newton_pair) error->all(FLERR,"Pair style lj/long/tip4p/long requires newton pair on"); if (!atom->q_flag) error->all(FLERR,"Pair style lj/long/tip4p/long requires atom attribute q"); if (force->bond == NULL) error->all(FLERR,"Must use a bond style with TIP4P potential"); if (force->angle == NULL) error->all(FLERR,"Must use an angle style with TIP4P potential"); PairLJLongCoulLong::init_style(); // set alpha parameter double theta = force->angle->equilibrium_angle(typeA); double blen = force->bond->equilibrium_distance(typeB); alpha = qdist / (cos(0.5*theta) * blen); } /* ---------------------------------------------------------------------- init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ double PairLJLongTIP4PLong::init_one(int i, int j) { double cut = PairLJLongCoulLong::init_one(i,j); // check that LJ epsilon = 0.0 for water H // set LJ cutoff to 0.0 for any interaction involving water H // so LJ term isn't calculated in compute() if ((i == typeH && epsilon[i][i] != 0.0)) error->all(FLERR,"Water H epsilon must be 0.0 for " "pair style lj/long/tip4p/long"); if (i == typeH || j == typeH) cut_ljsq[j][i] = cut_ljsq[i][j] = 0.0; return cut; } /* ---------------------------------------------------------------------- proc 0 writes to restart file ------------------------------------------------------------------------- */ void PairLJLongTIP4PLong::write_restart_settings(FILE *fp) { fwrite(&typeO,sizeof(int),1,fp); fwrite(&typeH,sizeof(int),1,fp); fwrite(&typeB,sizeof(int),1,fp); fwrite(&typeA,sizeof(int),1,fp); fwrite(&qdist,sizeof(double),1,fp); fwrite(&cut_lj_global,sizeof(double),1,fp); fwrite(&cut_coul,sizeof(double),1,fp); fwrite(&offset_flag,sizeof(int),1,fp); fwrite(&mix_flag,sizeof(int),1,fp); fwrite(&ncoultablebits,sizeof(int),1,fp); fwrite(&tabinner,sizeof(double),1,fp); } /* ---------------------------------------------------------------------- proc 0 reads from restart file, bcasts ------------------------------------------------------------------------- */ void PairLJLongTIP4PLong::read_restart_settings(FILE *fp) { if (comm->me == 0) { fread(&typeO,sizeof(int),1,fp); fread(&typeH,sizeof(int),1,fp); fread(&typeB,sizeof(int),1,fp); fread(&typeA,sizeof(int),1,fp); fread(&qdist,sizeof(double),1,fp); fread(&cut_lj_global,sizeof(double),1,fp); fread(&cut_coul,sizeof(double),1,fp); fread(&offset_flag,sizeof(int),1,fp); fread(&mix_flag,sizeof(int),1,fp); fread(&ncoultablebits,sizeof(int),1,fp); fread(&tabinner,sizeof(double),1,fp); } MPI_Bcast(&typeO,1,MPI_INT,0,world); MPI_Bcast(&typeH,1,MPI_INT,0,world); MPI_Bcast(&typeB,1,MPI_INT,0,world); MPI_Bcast(&typeA,1,MPI_INT,0,world); MPI_Bcast(&qdist,1,MPI_DOUBLE,0,world); MPI_Bcast(&cut_lj_global,1,MPI_DOUBLE,0,world); MPI_Bcast(&cut_coul,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(&ncoultablebits,1,MPI_INT,0,world); MPI_Bcast(&tabinner,1,MPI_DOUBLE,0,world); } /* ---------------------------------------------------------------------- compute position xM of fictitious charge site for O atom and 2 H atoms return it as xM ------------------------------------------------------------------------- */ void PairLJLongTIP4PLong::compute_newsite(double *xO, double *xH1, double *xH2, double *xM) { double delx1 = xH1[0] - xO[0]; double dely1 = xH1[1] - xO[1]; double delz1 = xH1[2] - xO[2]; double delx2 = xH2[0] - xO[0]; double dely2 = xH2[1] - xO[1]; double delz2 = xH2[2] - xO[2]; xM[0] = xO[0] + alpha * 0.5 * (delx1 + delx2); xM[1] = xO[1] + alpha * 0.5 * (dely1 + dely2); xM[2] = xO[2] + alpha * 0.5 * (delz1 + delz2); } /* ---------------------------------------------------------------------- */ void *PairLJLongTIP4PLong::extract(const char *str, int &dim) { dim = 0; if (strcmp(str,"qdist") == 0) return (void *) &qdist; if (strcmp(str,"typeO") == 0) return (void *) &typeO; if (strcmp(str,"typeH") == 0) return (void *) &typeH; if (strcmp(str,"typeA") == 0) return (void *) &typeA; if (strcmp(str,"typeB") == 0) return (void *) &typeB; if (strcmp(str,"cut_coul") == 0) return (void *) &cut_coul; const char *ids[] = { "B", "sigma", "epsilon", "ewald_order", "ewald_cut", "cut_coul", "ewald_mix", "cut_LJ", NULL}; void *ptrs[] = { lj4, sigma, epsilon, &ewald_order, &cut_coul, &cut_coul, &mix_flag, &cut_lj_global, NULL}; int i; i=0; while (ids[i] != NULL) { if (i <=2) dim = 2; else dim = 0; if (strcmp(ids[i],str) == 0) return ptrs[i]; ++i; } return NULL; } /* ---------------------------------------------------------------------- memory usage of hneigh ------------------------------------------------------------------------- */ double PairLJLongTIP4PLong::memory_usage() { double bytes = maxeatom * sizeof(double); bytes += maxvatom*6 * sizeof(double); bytes += 2 * nmax * sizeof(double); return bytes; } diff --git a/src/MANYBODY/pair_airebo.cpp b/src/MANYBODY/pair_airebo.cpp index d83f5a39a..0ca80c6b7 100644 --- a/src/MANYBODY/pair_airebo.cpp +++ b/src/MANYBODY/pair_airebo.cpp @@ -1,4295 +1,4291 @@ /* ---------------------------------------------------------------------- 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) / 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 dt2dik[3],dt2djl[3],dt2dij[3],aa,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 = 1.0/sqrt(1.0+Etmp+PijS); 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 = 1.0/sqrt(1.0+Etmp+PjiS); 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); // due to kronecker(ktype, 0) term in contribution // to NconjtmpI and later Nijconj if (ktype != 0) continue; 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); // due to kronecker(ltype, 0) term in contribution // to NconjtmpJ and later Nijconj if (ltype != 0) continue; 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 = -prefactor*(1.0-square(om1234)) * 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); // due to kronecker(ktype, 0) term in contribution // to NconjtmpI and later Nijconj if (ktype != 0) continue; 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); // due to kronecker(ltype, 0) term in contribution // to NconjtmpJ and later Nijconj if (ltype != 0) continue; 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 dN2[2],dN3[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 fcikpc,fcjlpc,fcjkpc,fcilpc; - double dt2dik[3],dt2djl[3],aa,aaa1,aaa2,at2,cw,cwnum,cwnom; + double dt2dik[3],dt2djl[3],aa,aaa2,at2,cw,cwnum,cwnom; double sin321,sin234,rr,rijrik,rijrjl,rjk2,rik2,ril2,rjl2; double dctik,dctjk,dctjl,dctil,rik2i,rjl2i,sink2i,sinl2i; double rjk[3],ril[3],dt1dik,dt1djk,dt1djl,dt1dil; 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],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 realrij[3], realrijmag; double rjkmag, rilmag, dctdjk, dctdik, dctdil, dctdjl; double fjk[3], fil[3], rijmbr; 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; realrij[0] = x[atomi][0] - x[atomj][0]; realrij[1] = x[atomi][1] - x[atomj][1]; realrij[2] = x[atomi][2] - x[atomj][2]; realrijmag = sqrt(realrij[0] * realrij[0] + realrij[1] * realrij[1] + realrij[2] * realrij[2]); 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 = 1.0/sqrt(1.0+Etmp+PijS); 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 = 1.0/sqrt(1.0+Etmp+PjiS); 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); rjk[0] = rik[0] - rij[0]; rjk[1] = rik[1] - rij[1]; rjk[2] = rik[2] - rij[2]; rjkmag = sqrt(rjk[0] * rjk[0] + rjk[1] * rjk[1] + rjk[2] * rjk[2]); rijrik = 2 * rijmag * rikmag; rr = rijmag * rijmag - rikmag * rikmag; cosjik = (rijmag * rijmag + rikmag * rikmag - rjkmag * rjkmag) / rijrik; cosjik = MIN(cosjik,1.0); cosjik = MAX(cosjik,-1.0); dctdjk = -2 / rijrik; dctdik = (-rr + rjkmag * rjkmag) / (rijrik * rikmag * rikmag); // evaluate splines g and derivatives dg g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN); tmp2 = VA*.5*(tmp*wik*dgdc*exp(lamdajik)); fi[0] = -tmp2 * dctdik * rik[0]; fi[1] = -tmp2 * dctdik * rik[1]; fi[2] = -tmp2 * dctdik * rik[2]; fk[0] = tmp2 * dctdik * rik[0]; fk[1] = tmp2 * dctdik * rik[1]; fk[2] = tmp2 * dctdik * rik[2]; fj[0] = 0; fj[1] = 0; fj[2] = 0; fjk[0] = -tmp2 * dctdjk * rjk[0]; fjk[1] = -tmp2 * dctdjk * rjk[1]; fjk[2] = -tmp2 * dctdjk * rjk[2]; fi[0] += fjk[0]; fi[1] += fjk[1]; fi[2] += fjk[2]; fk[0] -= fjk[0]; fk[1] -= fjk[1]; fk[2] -= fjk[2]; rijmbr = rcmin[itype][jtype] / realrijmag; fj[0] += rijmbr * (fjk[0] - (realrij[0] * realrij[0] * fjk[0] + realrij[0] * realrij[1] * fjk[1] + realrij[0] * realrij[2] * fjk[2]) / (realrijmag * realrijmag)); fj[1] += rijmbr * (fjk[1] - (realrij[1] * realrij[0] * fjk[0] + realrij[1] * realrij[1] * fjk[1] + realrij[1] * realrij[2] * fjk[2]) / (realrijmag * realrijmag)); fj[2] += rijmbr * (fjk[2] - (realrij[2] * realrij[0] * fjk[0] + realrij[2] * realrij[1] * fjk[1] + realrij[2] * realrij[2] * fjk[2]) / (realrijmag * realrijmag)); fi[0] -= rijmbr * (fjk[0] - (realrij[0] * realrij[0] * fjk[0] + realrij[0] * realrij[1] * fjk[1] + realrij[0] * realrij[2] * fjk[2]) / (realrijmag * realrijmag)); fi[1] -= rijmbr * (fjk[1] - (realrij[1] * realrij[0] * fjk[0] + realrij[1] * realrij[1] * fjk[1] + realrij[1] * realrij[2] * fjk[2]) / (realrijmag * realrijmag)); fi[2] -= rijmbr * (fjk[2] - (realrij[2] * realrij[0] * fjk[0] + realrij[2] * realrij[1] * fjk[1] + realrij[2] * realrij[2] * fjk[2]) / (realrijmag * realrijmag)); tmp2 = VA*.5*(tmp*wik*g*exp(lamdajik)*4.0*kronecker(itype,1)); fi[0] += tmp2*(rik[0]/rikmag); fi[1] += tmp2*(rik[1]/rikmag); fi[2] += tmp2*(rik[2]/rikmag); 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); ril[0] = rij[0] + rjl[0]; ril[1] = rij[1] + rjl[1]; ril[2] = rij[2] + rjl[2]; rilmag = sqrt(ril[0] * ril[0] + ril[1] * ril[1] + ril[2] * ril[2]); rijrjl = 2 * rijmag * rjlmag; rr = rijmag * rijmag - rjlmag * rjlmag; cosijl = (rijmag * rijmag + rjlmag * rjlmag - rilmag * rilmag) / rijrjl; cosijl = MIN(cosijl,1.0); cosijl = MAX(cosijl,-1.0); dctdil = -2 / rijrjl; dctdjl = (-rr + rilmag * rilmag) / (rijrjl * rjlmag * rjlmag); // evaluate splines g and derivatives dg g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN); tmp2 = VA*.5*(tmp*wjl*dgdc*exp(lamdaijl)); fj[0] = -tmp2 * dctdjl * rjl[0]; fj[1] = -tmp2 * dctdjl * rjl[1]; fj[2] = -tmp2 * dctdjl * rjl[2]; fl[0] = tmp2 * dctdjl * rjl[0]; fl[1] = tmp2 * dctdjl * rjl[1]; fl[2] = tmp2 * dctdjl * rjl[2]; fi[0] = 0; fi[1] = 0; fi[2] = 0; fil[0] = -tmp2 * dctdil * ril[0]; fil[1] = -tmp2 * dctdil * ril[1]; fil[2] = -tmp2 * dctdil * ril[2]; fj[0] += fil[0]; fj[1] += fil[1]; fj[2] += fil[2]; fl[0] -= fil[0]; fl[1] -= fil[1]; fl[2] -= fil[2]; rijmbr = rcmin[itype][jtype] / realrijmag; fi[0] += rijmbr * (fil[0] - (realrij[0] * realrij[0] * fil[0] + realrij[0] * realrij[1] * fil[1] + realrij[0] * realrij[2] * fil[2]) / (realrijmag * realrijmag)); fi[1] += rijmbr * (fil[1] - (realrij[1] * realrij[0] * fil[0] + realrij[1] * realrij[1] * fil[1] + realrij[1] * realrij[2] * fil[2]) / (realrijmag * realrijmag)); fi[2] += rijmbr * (fil[2] - (realrij[2] * realrij[0] * fil[0] + realrij[2] * realrij[1] * fil[1] + realrij[2] * realrij[2] * fil[2]) / (realrijmag * realrijmag)); fj[0] -= rijmbr * (fil[0] - (realrij[0] * realrij[0] * fil[0] + realrij[0] * realrij[1] * fil[1] + realrij[0] * realrij[2] * fil[2]) / (realrijmag * realrijmag)); fj[1] -= rijmbr * (fil[1] - (realrij[1] * realrij[0] * fil[0] + realrij[1] * realrij[1] * fil[1] + realrij[1] * realrij[2] * fil[2]) / (realrijmag * realrijmag)); fj[2] -= rijmbr * (fil[2] - (realrij[2] * realrij[0] * fil[0] + realrij[2] * realrij[1] * fil[1] + realrij[2] * realrij[2] * fil[2]) / (realrijmag * realrijmag)); tmp2 = VA*.5*(tmp*wjl*g*exp(lamdaijl)*4.0*kronecker(jtype,1)); fj[0] += tmp2*(rjl[0]/rjlmag); fj[1] += tmp2*(rjl[1]/rjlmag); fj[2] += tmp2*(rjl[2]/rjlmag); 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); // due to kronecker(ktype, 0) term in contribution // to NconjtmpI and later Nijconj if (ktype != 0) continue; 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); // due to kronecker(ltype, 0) term in contribution // to NconjtmpJ and later Nijconj if (ltype != 0) continue; 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] = -rij[0]; r32[1] = -rij[1]; r32[2] = -rij[2]; r23[0] = rij[0]; r23[1] = rij[1]; r23[2] = rij[2]; r32mag = rijmag; r23mag = rijmag; 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); 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); 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; dt1dik = (rik2i)-(dctik*sink2i*cos321); dt1djk = (-dctjk*sink2i*cos321); dt1djl = (rjl2i)-(dctjl*sinl2i*cos234); dt1dil = (-dctil*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]); 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 = -prefactor*(1.0-square(om1234)) * w21*w34; at2 = aa*cwnum; 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)); 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] = F12[0]+F31[0]; f2[1] = F12[1]+F31[1]; f2[2] = F12[2]+F31[2]; f3[0] = F34[0]+F24[0]; f3[1] = F34[1]+F24[1]; f3[2] = F34[2]+F24[2]; f4[0] = -F34[0]-F24[0]; f4[1] = -F34[1]-F24[1]; f4[2] = -F34[2]-F24[2]; rijmbr = rcmin[itype][jtype] / realrijmag; f2[0] += rijmbr * (F24[0] - (realrij[0] * realrij[0] * F24[0] + realrij[0] * realrij[1] * F24[1] + realrij[0] * realrij[2] * F24[2]) / (realrijmag * realrijmag)); f2[1] += rijmbr * (F24[1] - (realrij[1] * realrij[0] * F24[0] + realrij[1] * realrij[1] * F24[1] + realrij[1] * realrij[2] * F24[2]) / (realrijmag * realrijmag)); f2[2] += rijmbr * (F24[2] - (realrij[2] * realrij[0] * F24[0] + realrij[2] * realrij[1] * F24[1] + realrij[2] * realrij[2] * F24[2]) / (realrijmag * realrijmag)); f3[0] -= rijmbr * (F24[0] - (realrij[0] * realrij[0] * F24[0] + realrij[0] * realrij[1] * F24[1] + realrij[0] * realrij[2] * F24[2]) / (realrijmag * realrijmag)); f3[1] -= rijmbr * (F24[1] - (realrij[1] * realrij[0] * F24[0] + realrij[1] * realrij[1] * F24[1] + realrij[1] * realrij[2] * F24[2]) / (realrijmag * realrijmag)); f3[2] -= rijmbr * (F24[2] - (realrij[2] * realrij[0] * F24[0] + realrij[2] * realrij[1] * F24[1] + realrij[2] * realrij[2] * F24[2]) / (realrijmag * realrijmag)); f2[0] -= rijmbr * (F31[0] - (realrij[0] * realrij[0] * F31[0] + realrij[0] * realrij[1] * F31[1] + realrij[0] * realrij[2] * F31[2]) / (realrijmag * realrijmag)); f2[1] -= rijmbr * (F31[1] - (realrij[1] * realrij[0] * F31[0] + realrij[1] * realrij[1] * F31[1] + realrij[1] * realrij[2] * F31[2]) / (realrijmag * realrijmag)); f2[2] -= rijmbr * (F31[2] - (realrij[2] * realrij[0] * F31[0] + realrij[2] * realrij[1] * F31[1] + realrij[2] * realrij[2] * F31[2]) / (realrijmag * realrijmag)); f3[0] += rijmbr * (F31[0] - (realrij[0] * realrij[0] * F31[0] + realrij[0] * realrij[1] * F31[1] + realrij[0] * realrij[2] * F31[2]) / (realrijmag * realrijmag)); f3[1] += rijmbr * (F31[1] - (realrij[1] * realrij[0] * F31[0] + realrij[1] * realrij[1] * F31[1] + realrij[1] * realrij[2] * F31[2]) / (realrijmag * realrijmag)); f3[2] += rijmbr * (F31[2] - (realrij[2] * realrij[0] * F31[0] + realrij[2] * realrij[1] * F31[1] + realrij[2] * realrij[2] * F31[2]) / (realrijmag * realrijmag)); // 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); // due to kronecker(ktype, 0) term in contribution // to NconjtmpI and later Nijconj if (ktype != 0) continue; 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); // due to kronecker(ltype, 0) term in contribution // to NconjtmpJ and later Nijconj if (ltype != 0) continue; 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; double Pij; x = 0; y = 0; dN2[0] = 0.0; dN2[1] = 0.0; Pij = 0.0; if (typei == 1) return Pij; if (typej == 0) { // if inputs are out of bounds set them back to a point in bounds 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]; x = (int) floor(NijC); y = (int) floor(NijH); if (fabs(NijC-floor(NijC)) < TOL && fabs(NijH-floor(NijH)) < TOL) { Pij = PCCf[x][y]; dN2[0] = PCCdfdx[x][y]; dN2[1] = PCCdfdy[x][y]; } else { if (NijC == pCCdom[0][1]) --x; if (NijH == pCCdom[1][1]) --y; Pij = Spbicubic(NijC,NijH,pCC[x][y],dN2); } } else if (typej == 1) { // if inputs are out of bounds set them back to a point in bounds 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]; x = (int) floor(NijC); y = (int) floor(NijH); if (fabs(NijC-floor(NijC)) < TOL && fabs(NijH-floor(NijH)) < TOL) { Pij = PCHf[x][y]; dN2[0] = PCHdfdx[x][y]; dN2[1] = PCHdfdy[x][y]; } else { if (NijC == pCHdom[0][1]) --x; if (NijH == pCHdom[1][1]) --y; Pij = Spbicubic(NijC,NijH,pCH[x][y],dN2); } } return Pij; } /* ---------------------------------------------------------------------- PiRC spline ------------------------------------------------------------------------- */ double PairAIREBO::piRCSpline(double Nij, double Nji, double Nijconj, int typei, int typej, double dN3[3]) { int x,y,z; double piRC; x=0; y=0; z=0; dN3[0]=0.0; dN3[1]=0.0; dN3[2]=0.0; if (typei==0 && typej==0) { // CC interaction // if the inputs are out of bounds set them back to a point in bounds if (Nij < piCCdom[0][0]) Nij=piCCdom[0][0]; if (Nij > piCCdom[0][1]) Nij=piCCdom[0][1]; if (Nji < piCCdom[1][0]) Nji=piCCdom[1][0]; if (Nji > piCCdom[1][1]) Nji=piCCdom[1][1]; if (Nijconj < piCCdom[2][0]) Nijconj=piCCdom[2][0]; if (Nijconj > piCCdom[2][1]) Nijconj=piCCdom[2][1]; x = (int) floor(Nij); y = (int) floor(Nji); z = (int) floor(Nijconj); if (fabs(Nij-floor(Nij)) < TOL && fabs(Nji-floor(Nji)) < TOL && fabs(Nijconj-floor(Nijconj)) < TOL) { piRC=piCCf[x][y][z]; dN3[0]=piCCdfdx[x][y][z]; dN3[1]=piCCdfdy[x][y][z]; dN3[2]=piCCdfdz[x][y][z]; } else { if (Nij == piCCdom[0][1]) --x; if (Nji == piCCdom[1][1]) --y; if (Nijconj == piCCdom[2][1]) --z; piRC=Sptricubic(Nij,Nji,Nijconj,piCC[x][y][z],dN3); } } else if ((typei==0 && typej==1) || (typei==1 && typej==0)) { // CH interaction // if the inputs are out of bounds set them back to a point in bounds if (Nij < piCHdom[0][0]) Nij=piCHdom[0][0]; if (Nij > piCHdom[0][1]) Nij=piCHdom[0][1]; if (Nji < piCHdom[1][0]) Nji=piCHdom[1][0]; if (Nji > piCHdom[1][1]) Nji=piCHdom[1][1]; if (Nijconj < piCHdom[2][0]) Nijconj=piCHdom[2][0]; if (Nijconj > piCHdom[2][1]) Nijconj=piCHdom[2][1]; x = (int) floor(Nij); y = (int) floor(Nji); z = (int) floor(Nijconj); if (fabs(Nij-floor(Nij)) < TOL && fabs(Nji-floor(Nji)) < TOL && fabs(Nijconj-floor(Nijconj)) < TOL) { piRC=piCHf[x][y][z]; dN3[0]=piCHdfdx[x][y][z]; dN3[1]=piCHdfdy[x][y][z]; dN3[2]=piCHdfdz[x][y][z]; } else { if (Nij == piCHdom[0][1]) --x; if (Nji == piCHdom[1][1]) --y; if (Nijconj == piCHdom[2][1]) --z; piRC=Sptricubic(Nij,Nji,Nijconj,piCH[x][y][z],dN3); } } else if (typei==1 && typej==1) { if (Nij < piHHdom[0][0]) Nij=piHHdom[0][0]; if (Nij > piHHdom[0][1]) Nij=piHHdom[0][1]; if (Nji < piHHdom[1][0]) Nji=piHHdom[1][0]; if (Nji > piHHdom[1][1]) Nji=piHHdom[1][1]; if (Nijconj < piHHdom[2][0]) Nijconj=piHHdom[2][0]; if (Nijconj > piHHdom[2][1]) Nijconj=piHHdom[2][1]; x = (int) floor(Nij); y = (int) floor(Nji); z = (int) floor(Nijconj); if (fabs(Nij-floor(Nij)) < TOL && fabs(Nji-floor(Nji)) < TOL && fabs(Nijconj-floor(Nijconj)) < TOL) { piRC=piHHf[x][y][z]; dN3[0]=piHHdfdx[x][y][z]; dN3[1]=piHHdfdy[x][y][z]; dN3[2]=piHHdfdz[x][y][z]; } else { if (Nij == piHHdom[0][1]) --x; if (Nji == piHHdom[1][1]) --y; if (Nijconj == piHHdom[2][1]) --z; piRC=Sptricubic(Nij,Nji,Nijconj,piHH[x][y][z],dN3); } } return piRC; } /* ---------------------------------------------------------------------- Tij spline ------------------------------------------------------------------------- */ double PairAIREBO::TijSpline(double Nij, double Nji, double Nijconj, double dN3[3]) { int x,y,z; double Tijf; x=0; y=0; z=0; Tijf=0.0; dN3[0]=0.0; dN3[1]=0.0; dN3[2]=0.0; //if the inputs are out of bounds set them back to a point in bounds if (Nij < Tijdom[0][0]) Nij=Tijdom[0][0]; if (Nij > Tijdom[0][1]) Nij=Tijdom[0][1]; if (Nji < Tijdom[1][0]) Nji=Tijdom[1][0]; if (Nji > Tijdom[1][1]) Nji=Tijdom[1][1]; if (Nijconj < Tijdom[2][0]) Nijconj=Tijdom[2][0]; if (Nijconj > Tijdom[2][1]) Nijconj=Tijdom[2][1]; x = (int) floor(Nij); y = (int) floor(Nji); z = (int) floor(Nijconj); if (fabs(Nij-floor(Nij)) < TOL && fabs(Nji-floor(Nji)) < TOL && fabs(Nijconj-floor(Nijconj)) < TOL) { Tijf=Tf[x][y][z]; dN3[0]=Tdfdx[x][y][z]; dN3[1]=Tdfdy[x][y][z]; dN3[2]=Tdfdz[x][y][z]; } else { if (Nij == Tijdom[0][1]) --x; if (Nji == Tijdom[1][1]) --y; if (Nijconj == Tijdom[2][1]) --z; Tijf=Sptricubic(Nij,Nji,Nijconj,Tijc[x][y][z],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; // 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_bop.h b/src/MANYBODY/pair_bop.h index d55d9a79a..f50c5edd0 100644 --- a/src/MANYBODY/pair_bop.h +++ b/src/MANYBODY/pair_bop.h @@ -1,289 +1,289 @@ -/* ---------------------------------------------------------------------- +/* -*- 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. The this work follows the formulation from (a) D.G. Pettifor, et al., Mat. Sci. and Eng. A365, 2-13, (2004) and (b) D.A. Murdick, et al., Phys. Rev. B 73, 045206 (2006). (c) D.K. Ward, et al., Phys. Rev. B 85, 115206 (2012) See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ #ifdef PAIR_CLASS PairStyle(bop,PairBOP) #else #ifndef LMP_PAIR_BOP_H #define LMP_PAIR_BOP_H #include "pair.h" #include #include "update.h" namespace LAMMPS_NS { class PairBOP : public Pair { public: PairBOP(class LAMMPS *); virtual ~PairBOP(); void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); double init_one(int, int); double memory_usage(); private: int me; int maxneigh; // maximum size of neighbor list on this processor int maxneigh3; // maximum size of neighbor list on this processor int update_list; // check for changing maximum size of neighbor list int maxbopn; // maximum size of bop neighbor list for allocation int maxnall; // maximum size of bop neighbor list for allocation int *map; // mapping from atom types to elements int nelements; // # of unique elments int nr; // increments for the BOP pair potential int ntheta; // increments for the angle function int npower; // power of the angular function int nBOt; // second BO increments int bop_types; // number of elments in potential int npairs; // number of element pairs char **elements; // names of unique elements int ***elem2param; int nparams; int bop_step; int allocate_pi; int allocate_sigma; int allocate_neigh; int nb_pi,nb_sg; int ago1; // int cnt1; int *BOP_index; // index for neighbor list position int *BOP_total; // index for neighbor list position int *BOP_index3; // index for neighbor list position int *BOP_total3; // index for neighbor list position int *neigh_index; // index for neighbor list position int *neigh_index3; // index for neighbor list position int neigh_total; // total number of neighbors stored int neigh_total3; // total number of neighbors stored int *cos_index; // index for neighbor cosine if not using on the fly int *neigh_flag; // index for neighbor cosine if not using on the fly int *neigh_flag3; // index for neighbor cosine if not using on the fly int cos_total; // number of cosines stored if not using on the fly int neigh_ct; // limit for large arrays /*Parameters variables*/ int ncutoff,nfunc; int a_flag; double *pi_a,*pro_delta,*pi_delta; double *pi_p,*pi_c,*sigma_r0,*pi_r0,*phi_r0; double *sigma_rc,*pi_rc,*phi_rc,*r1,*sigma_beta0; double *pi_beta0,*phi0,*sigma_n,*pi_n,*phi_m; double *sigma_nc,*pi_nc,*phi_nc; double *pro,*sigma_delta,*sigma_c,*sigma_a; double *sigma_f,*sigma_k,*small3; double small1,small2,small3g,small4,small5,small6,small7; double which,alpha,alpha1,beta1,gamma1,alpha2,beta2,alpha3; double beta3,rsmall,rbig,rcore; char **words; double cutmax; //max cutoff for all elements int otfly; //Defines whether to do on the fly //calculations of angles and distances //on the fly will slow down calculations //but requires less memory on = 1, off=0 /* Neigh variables */ double *rcut,*rcut3,*dr,*rdr,*dr3,*rdr3; double *rcutsq,*rcutsq3; double **disij,*rij; double rcutall,rctroot; /*Triple variables */ double *cosAng,***dcosAng,***dcAng; /*Double variables */ double *betaS,*dBetaS,*betaP; double *dBetaP,*repul,*dRepul; /*Sigma variables */ int *itypeSigBk,nSigBk; double sigB,sigB_0; double sigB1; /*Pi variables */ int *itypePiBk,nPiBk; double piB,piB_0; /*Grids1 variables */ double **pBetaS,**pBetaS1,**pBetaS2,**pBetaS3; double **pBetaS4,**pBetaS5,**pBetaS6; /*Grids2 variables */ double **pBetaP,**pBetaP1,**pBetaP2,**pBetaP3; double **pBetaP4,**pBetaP5,**pBetaP6; /*Grids3 variables */ double **pRepul,**pRepul1,**pRepul2,**pRepul3; double **pRepul4,**pRepul5,**pRepul6; double **pLong,**pLong1,**pLong2,**pLong3; double **pLong4,**pLong5,**pLong6; double ****gfunc,****gpara; double ****gfunc1,****gfunc2,****gfunc3; double ****gfunc4,****gfunc5,****gfunc6; double dtheta,rdtheta; /*Grids4 variables */ double **FsigBO,**FsigBO1,**FsigBO2,**FsigBO3; double **FsigBO4,**FsigBO5,**FsigBO6; double dBO,rdBO; /* End of BOP variables */ double **rcmin,**rcmax,**rcmaxp; struct B_PI{ double dAA[3]; double dBB[3]; double dPiB[3]; int temp; int i; int j; }; B_PI *bt_pi; struct B_SG{ double dAA[3]; double dBB[3]; double dCC[3]; double dDD[3]; double dEE[3]; double dEE1[3]; double dFF[3]; double dAAC[3]; double dBBC[3]; double dCCC[3]; double dDDC[3]; double dEEC[3]; double dFFC[3]; double dGGC[3]; double dUT[3]; double dSigB1[3]; double dSigB[3]; int temp; int i; int j; }; B_SG *bt_sg; void setPbetaS(); void setPbetaP(); void setPrepul(); void setSign(); void gneigh(); void theta(); void theta_mod(); double sigmaBo(int, int); double PiBo(int, int); void memory_theta_create(); void memory_theta_destroy(); void memory_theta_grow(); double cutoff(double, double, int, double); /* double betaSfunc(int, double); double dBetaSfunc(int, double, double, double); double betaPfunc(int, double); double dBetaPfunc(int, double, double, double); double repulfunc(int, double); double dRepulfunc(int, double, double, double); */ void read_table(char *); void allocate(); void create_pi(int); void create_sigma(int); void destroy_pi(); void destroy_sigma(); void grow_pi(int,int); void grow_sigma(int,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: Incorrect args for pair coefficients Self-explanatory. Check the input script or data file. E: Pair style BOP requires atom IDs This is a requirement to use the BOP potential. E: Pair style BOP requires newton pair on See the newton command. This is a restriction to use the BOP potential. E: Pair style bop requires comm ghost cutoff at least 3x larger than %g Use the communicate ghost command to set this. See the pair bop doc page for more details. 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: Too many atom pairs for pair bop The number of atomic pairs exceeds the expected number. Check your atomic structure to ensure that it is realistic. E: Too many atom triplets for pair bop The number of three atom groups for angle determinations exceeds the expected number. Check your atomic structure to ensure that it is realistic. E: Cannot open BOP potential file %s The specified BOP potential file cannot be opened. Check that the path and name are correct. E: Incorrect table format check for element types Self-explanatory. */ diff --git a/src/MANYBODY/pair_polymorphic.h b/src/MANYBODY/pair_polymorphic.h index 9b7fe761b..9917bcd96 100644 --- a/src/MANYBODY/pair_polymorphic.h +++ b/src/MANYBODY/pair_polymorphic.h @@ -1,360 +1,360 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(polymorphic,PairPolymorphic) #else #ifndef LMP_PAIR_POLYMORPHIC_H #define LMP_PAIR_POLYMORPHIC_H #include "pair.h" namespace LAMMPS_NS { class PairPolymorphic : public Pair { public: PairPolymorphic(class LAMMPS *); virtual ~PairPolymorphic(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); double init_one(int, int); protected: class tabularFunction { public: tabularFunction() { size = 0; xmin = 0.0; xmax = 0.0; xmaxsq = xmax*xmax; vmax = 0.0; xs = NULL; ys = NULL; ys1 = NULL; ys2 = NULL; ys3 = NULL; ys4 = NULL; ys5 = NULL; ys6 = NULL; } tabularFunction(int n) { size = n; xmin = 0.0; xmax = 0.0; xmaxsq = xmax*xmax; xs = new double[n]; ys = new double[n]; ys1 = new double[n]; ys2 = new double[n]; ys3 = new double[n]; ys4 = new double[n]; ys5 = new double[n]; ys6 = new double[n]; } tabularFunction(int n, double x1, double x2) { size = n; xmin = x1; xmax = x2; xmaxsq = xmax*xmax; xs = new double[n]; ys = new double[n]; ys1 = new double[n]; ys2 = new double[n]; ys3 = new double[n]; ys4 = new double[n]; ys5 = new double[n]; ys6 = new double[n]; } virtual ~tabularFunction() { if (xs) delete [] xs; if (ys) delete [] ys; if (ys1) delete [] ys1; if (ys2) delete [] ys2; if (ys3) delete [] ys3; if (ys4) delete [] ys4; if (ys5) delete [] ys5; if (ys6) delete [] ys6; } void set_xrange(double x1, double x2) { xmin = x1; xmax = x2; xmaxsq = xmax*xmax; } void set_values(int n, double x1, double x2, double * values, double epsilon) { int i0; i0 = n-1; // shrink (remove near zero points) reduces cutoff radius, and therefore computational cost // do not shrink when x2 < 1.1 (angular function) or x2 > 20.0 (non-radial function) if (x2 >= 1.1 && x2 <= 20.0) { for (int i = n-1; i >= 0; i--) { if (fabs(values[i]) > epsilon) { i0 = i; break; } } } // do not shrink when when list is abnormally small if (i0 < 10/n) { i0 = n-1; } else if (i0 < n-1) { values[i0] = 0.0; i0 = i0 + 1; values[i0] = 0.0; } xmin = x1; xmax = x1 + (x2-x1)/(n -1)*i0; xmaxsq = xmax*xmax; n = i0+1; resize(n); memcpy(ys,values,n*sizeof(double)); initialize(); } void value(double x, double &y, int ny, double &y1, int ny1) { double ps = (x - xmin) * rdx; int ks = ps + 0.5; if (ks > size-1) ks = size-1; if (ks < 0 ) ks = 0; ps = ps - ks; if (ny) y = ((ys3[ks]*ps + ys2[ks])*ps + ys1[ks])*ps + ys[ks]; if (ny1) y1 = (ys6[ks]*ps + ys5[ks])*ps + ys4[ks]; } void print_value() { printf("%d %f %f %f \n",size,xmin,xmax,rdx); printf(" \n"); for (int i = 0; i < size; i++) { printf("%f %f \n",xs[i],ys[i]); } } double get_xmin() { return xmin; } double get_xmax() { return xmax; } double get_xmaxsq() { return xmaxsq; } double get_rdx() { return rdx; } double get_vmax() { return vmax; } protected: void resize(int n) { if (n != size) { size = n; if (xs) delete [] xs; xs = new double[n]; if (ys) delete [] ys; ys = new double[n]; if (ys1) delete [] ys1; ys1 = new double[n]; if (ys2) delete [] ys2; ys2 = new double[n]; if (ys3) delete [] ys3; ys3 = new double[n]; if (ys4) delete [] ys4; ys4 = new double[n]; if (ys5) delete [] ys5; ys5 = new double[n]; if (ys6) delete [] ys6; ys6 = new double[n]; } } void initialize() { int n = size; rdx = (xmax-xmin)/(n-1.0); vmax = 0.0; for (int i = 0; i < n; i++) { if (fabs(ys[i]) > vmax) vmax = fabs(ys[i]); } for (int i = 0; i < n; i++) { xs[i] = xmin+i*rdx; } rdx = 1.0 / rdx; ys1[0] = ys[1] - ys[0]; ys1[1] = 0.5 * (ys[2] - ys[0]); ys1[n-2] = 0.5 * (ys[n-1] - ys[n-3]); ys1[n-1] = ys[n-1] - ys[n-2]; for (int i = 2; i < n-2; i++) { ys1[i]=((ys[i-2]-ys[i+2])+ 8.0*(ys[i+1]-ys[i-1]))/12.0; } for (int i = 0; i < n-1; i++) { ys2[i]=3.0*(ys[i+1]-ys[i])-2.0*ys1[i]-ys1[i+1]; ys3[i]=ys1[i]+ys1[i+1]-2.0*(ys[i+1]-ys[i]); } ys2[n-1]=0.0; ys3[n-1]=0.0; for (int i = 0; i < n; i++) { ys4[i]=ys1[i]*rdx; ys5[i]=2.0*ys2[i]*rdx; ys6[i]=3.0*ys3[i]*rdx; } } int size; double xmin,xmax,xmaxsq,rdx,vmax; double * ys, * ys1, * ys2, * ys3, * ys4, * ys5, * ys6; double * xs; }; struct PairParameters { double cut; double cutsq; bool xi; // "indicator" class tabularFunction * U; class tabularFunction * V; class tabularFunction * W; class tabularFunction * P; class tabularFunction * F; PairParameters() { cut = 0.0; cutsq = 0.0; xi = true; U = NULL; V = NULL; W = NULL; P = NULL; F = NULL; }; }; struct TripletParameters { class tabularFunction * G; TripletParameters() { G = NULL; }; }; double epsilon; bool eta; // global indicator int nx,nr,ng; // table sizes double maxX; // parameter sets PairParameters * pairParameters; // for I-J interaction TripletParameters * tripletParameters; // for I-J-K interaction int neighsize,numneighV,numneighW,numneighW1; int *firstneighV,*firstneighW,*firstneighW1; double *delxV,*delyV,*delzV,*drV; double *delxW,*delyW,*delzW,*drW; char **elements; // names of unique elements int **elem2param; // map: element pairs to parameters int ***elem3param; // map: element triplets to parameters int *map; // mapping from atom types to elements double cutmax; // max cutoff for all elements double cutmaxsq; int nelements; // # of unique elements int npair,ntriple; int *match; void allocate(); void grab(FILE *, int, double *); virtual void read_file(char *); void setup_params(); void write_tables(int); void attractive(PairParameters *, TripletParameters *, double, double, double, double *, double *, double *, double *, double *); void ters_zetaterm_d(double, double *, double, double *, double, double *, double *, double *, PairParameters *, TripletParameters *); void costheta_d(double *, double, double *, double, double *, double *, double *); // inlined functions for efficiency inline double vec3_dot(const double x[3], const double y[3]) const { return x[0]*y[0] + x[1]*y[1] + x[2]*y[2]; } inline void vec3_add(const double x[3], const double y[3], double * const z) const { z[0] = x[0]+y[0]; z[1] = x[1]+y[1]; z[2] = x[2]+y[2]; } inline void vec3_scale(const double k, const double x[3], double y[3]) const { y[0] = k*x[0]; y[1] = k*x[1]; y[2] = k*x[2]; } inline void vec3_scaleadd(const double k, const double x[3], const double y[3], double * const z) const { z[0] = k*x[0]+y[0]; z[1] = k*x[1]+y[1]; z[2] = k*x[2]+y[2]; } }; } #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 polymorphic requires atom IDs This is a requirement to use the polymorphic potential. E: Pair style polymorphic requires newton pair on See the newton command. This is a restriction to use the polymorphic 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: Cannot open polymorphic potential file %s The specified polymorphic potential file cannot be opened. Check that the path and name are correct. E: Incorrect number of elements in potential file Self-explanatory. E: Element not defined in potential file The specified element is not in the potential file. */ diff --git a/src/MANYBODY/pair_vashishta_table.h b/src/MANYBODY/pair_vashishta_table.h index a45cac5ae..8c52f967c 100644 --- a/src/MANYBODY/pair_vashishta_table.h +++ b/src/MANYBODY/pair_vashishta_table.h @@ -1,100 +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. ------------------------------------------------------------------------- */ #ifdef PAIR_CLASS PairStyle(vashishta/table,PairVashishtaTable) #else #ifndef LMP_PAIR_VASHISHITA_TABLE_H #define LMP_PAIR_VASHISHITA_TABLE_H #include "pair_vashishta.h" namespace LAMMPS_NS { class PairVashishtaTable : public PairVashishta { public: PairVashishtaTable(class LAMMPS *); ~PairVashishtaTable(); void compute(int, int); void settings(int, char **); double memory_usage(); protected: int ntable; double deltaR2; double oneOverDeltaR2; double ***forceTable; // table of forces per element pair double ***potentialTable; // table of potential energies void twobody_table(const Param &, double, double &, int, double &); void setup_params(); void create_tables(); }; } #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 Vashishta requires atom IDs This is a requirement to use the Vashishta potential. E: Pair style Vashishta requires newton pair on See the newton command. This is a restriction to use the Vashishta 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: Cannot open Vashishta potential file %s The specified Vashishta potential file cannot be opened. Check that the path and name are correct. E: Incorrect format in Vashishta potential file Incorrect number of words per line in the potential file. E: Illegal Vashishta parameter One or more of the coefficients defined in the potential file is invalid. E: Potential file has duplicate entry The potential file has more than one entry for the same element. E: Potential file is missing an entry The potential file does not have a needed entry. */ diff --git a/src/MC/fix_atom_swap.h b/src/MC/fix_atom_swap.h index 25208a2b5..74720d622 100644 --- a/src/MC/fix_atom_swap.h +++ b/src/MC/fix_atom_swap.h @@ -1,145 +1,145 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(atom/swap,FixAtomSwap) #else #ifndef LMP_FIX_MCSWAP_H #define LMP_FIX_MCSWAP_H #include #include "fix.h" namespace LAMMPS_NS { class FixAtomSwap : public Fix { public: FixAtomSwap(class LAMMPS *, int, char **); ~FixAtomSwap(); int setmask(); void init(); void pre_exchange(); int attempt_semi_grand(); int attempt_swap(); double energy_full(); int pick_semi_grand_atom(); int pick_i_swap_atom(); int pick_j_swap_atom(); void update_semi_grand_atoms_list(); void update_swap_atoms_list(); int pack_forward_comm(int, int *, double *, int, int *); void unpack_forward_comm(int, int, double *); double compute_vector(int); double memory_usage(); void write_restart(FILE *); void restart(char *); private: int nevery,seed; int conserve_ke_flag; // yes = conserve ke, no = do not conserve ke int semi_grand_flag; // yes = semi-grand canonical, no = constant composition int ncycles; int niswap,njswap; // # of i,j swap atoms on all procs int niswap_local,njswap_local; // # of swap atoms on this proc int niswap_before,njswap_before; // # of swap atoms on procs < this proc int nswap; // # of swap atoms on all procs int nswap_local; // # of swap atoms on this proc int nswap_before; // # of swap atoms on procs < this proc int regionflag; // 0 = anywhere in box, 1 = specific region int iregion; // swap region char *idregion; // swap region id int nswaptypes,nmutypes; int *type_list; double *mu; double nswap_attempts; double nswap_successes; bool unequal_cutoffs; int atom_swap_nmax; double beta; double *qtype; double energy_stored; double **sqrt_mass_ratio; int *local_swap_iatom_list; int *local_swap_jatom_list; int *local_swap_atom_list; class RanPark *random_equal; class RanPark *random_unequal; class Compute *c_pe; void options(int, char **); }; } #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 ID for fix atom/swap does not exist Self-explanatory. E: Must specify at least 2 types in fix atom/swap command Self-explanatory. E: Need nswaptypes mu values in fix atom/swap command Self-explanatory. E: Only 2 types allowed when not using semi-grand in fix atom/swap command Self-explanatory. E: Mu not allowed when not using semi-grand in fix atom/swap command Self-explanatory. E: Invalid atom type in fix atom/swap command The atom type specified in the atom/swap command does not exist. E: All atoms of a swapped type must have the same charge. Self-explanatory. E: At least one atom of each swapped type must be present to define charges. Self-explanatory. E: All atoms of a swapped type must have same charge. Self-explanatory. E: Cannot do atom/swap on atoms in atom_modify first group This is a restriction due to the way atoms are organized in a list to enable the atom_modify first command. */ diff --git a/src/MC/fix_gcmc.h b/src/MC/fix_gcmc.h index 8a5375eed..3656a1df5 100644 --- a/src/MC/fix_gcmc.h +++ b/src/MC/fix_gcmc.h @@ -1,304 +1,304 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(gcmc,FixGCMC) #else #ifndef LMP_FIX_GCMC_H #define LMP_FIX_GCMC_H #include #include "fix.h" namespace LAMMPS_NS { class FixGCMC : public Fix { public: FixGCMC(class LAMMPS *, int, char **); ~FixGCMC(); int setmask(); void init(); void pre_exchange(); void attempt_atomic_translation(); void attempt_atomic_deletion(); void attempt_atomic_insertion(); void attempt_molecule_translation(); void attempt_molecule_rotation(); void attempt_molecule_deletion(); void attempt_molecule_insertion(); void attempt_atomic_translation_full(); void attempt_atomic_deletion_full(); void attempt_atomic_insertion_full(); void attempt_molecule_translation_full(); void attempt_molecule_rotation_full(); void attempt_molecule_deletion_full(); void attempt_molecule_insertion_full(); double energy(int, int, tagint, double *); double molecule_energy(tagint); double energy_full(); int pick_random_gas_atom(); tagint pick_random_gas_molecule(); void toggle_intramolecular(int); void update_gas_atoms_list(); double compute_vector(int); double memory_usage(); void write_restart(FILE *); void restart(char *); private: int molecule_group,molecule_group_bit; int molecule_group_inversebit; int exclusion_group,exclusion_group_bit; int ngcmc_type,nevery,seed; int ncycles,nexchanges,nmcmoves; int ngas; // # of gas atoms on all procs int ngas_local; // # of gas atoms on this proc int ngas_before; // # of gas atoms on procs < this proc int mode; // ATOM or MOLECULE int regionflag; // 0 = anywhere in box, 1 = specific region int iregion; // gcmc region char *idregion; // gcmc region id bool pressure_flag; // true if user specified reservoir pressure bool charge_flag; // true if user specified atomic charge bool full_flag; // true if doing full system energy calculations int natoms_per_molecule; // number of atoms in each gas molecule int groupbitall; // group bitmask for inserted atoms int ngroups; // number of group-ids for inserted atoms char** groupstrings; // list of group-ids for inserted atoms int ngrouptypes; // number of type-based group-ids for inserted atoms char** grouptypestrings; // list of type-based group-ids for inserted atoms int* grouptypebits; // list of type-based group bitmasks int* grouptypes; // list of type-based group types double ntranslation_attempts; double ntranslation_successes; double nrotation_attempts; double nrotation_successes; double ndeletion_attempts; double ndeletion_successes; double ninsertion_attempts; double ninsertion_successes; int gcmc_nmax; int max_region_attempts; double gas_mass; double reservoir_temperature; double tfac_insert; double chemical_potential; double displace; double max_rotation_angle; double beta,zz,sigma,volume; double pressure,fugacity_coeff,charge; double xlo,xhi,ylo,yhi,zlo,zhi; double region_xlo,region_xhi,region_ylo,region_yhi,region_zlo,region_zhi; double region_volume; double energy_stored; // full energy of old/current configuration double *sublo,*subhi; int *local_gas_list; double **cutsq; double **atom_coord; imageint imagezero; double overlap_cutoffsq; // square distance cutoff for overlap int overlap_flag; double energy_intra; class Pair *pair; class RanPark *random_equal; class RanPark *random_unequal; class Atom *model_atom; class Molecule **onemols; int imol,nmol; double **coords; imageint *imageflags; class Fix *fixrigid, *fixshake; int rigidflag, shakeflag; char *idrigid, *idshake; int triclinic; // 0 = orthog box, 1 = triclinic class Compute *c_pe; void options(int, char **); }; } #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 gcmc does not (yet) work with atom_style template Self-explanatory. E: Fix gcmc region does not support a bounding box Not all regions represent bounded volumes. You cannot use such a region with the fix gcmc command. E: Fix gcmc region cannot be dynamic Only static regions can be used with fix gcmc. E: Fix gcmc region extends outside simulation box Self-explanatory. E: Fix gcmc molecule must have coordinates The defined molecule does not specify coordinates. E: Fix gcmc molecule must have atom types The defined molecule does not specify atom types. E: Atom type must be zero in fix gcmc mol command Self-explanatory. E: Fix gcmc molecule has charges, but atom style does not Self-explanatory. E: Fix gcmc molecule template ID must be same as atom_style template ID When using atom_style template, you cannot insert molecules that are not in that template. E: Fix gcmc atom has charge, but atom style does not Self-explanatory. E: Cannot use fix gcmc shake and not molecule Self-explanatory. E: Molecule template ID for fix gcmc does not exist Self-explanatory. W: Molecule template for fix gcmc has multiple molecules The fix gcmc command will only create molecules of a single type, i.e. the first molecule in the template. E: Region ID for fix gcmc does not exist Self-explanatory. W: Fix gcmc using full_energy option Fix gcmc has automatically turned on the full_energy option since it is required for systems like the one specified by the user. User input included one or more of the following: kspace, a hybrid pair style, an eam pair style, tail correction, or no "single" function for the pair style. W: Energy of old configuration in fix gcmc is > MAXENERGYTEST. This probably means that a pair of atoms are closer than the overlap cutoff distance for keyword overlap_cutoff. E: Invalid atom type in fix gcmc command The atom type specified in the gcmc command does not exist. E: Fix gcmc cannot exchange individual atoms belonging to a molecule This is an error since you should not delete only one atom of a molecule. The user has specified atomic (non-molecular) gas exchanges, but an atom belonging to a molecule could be deleted. E: All mol IDs should be set for fix gcmc group atoms The molecule flag is on, yet not all molecule ids in the fix group have been set to non-zero positive values by the user. This is an error since all atoms in the fix gcmc group are eligible for deletion, rotation, and translation and therefore must have valid molecule ids. E: Fix gcmc molecule command requires that atoms have molecule attributes Should not choose the gcmc molecule feature if no molecules are being simulated. The general molecule flag is off, but gcmc's molecule flag is on. E: Fix gcmc shake fix does not exist Self-explanatory. E: Fix gcmc and fix shake not using same molecule template ID Self-explanatory. E: Fix gcmc can not currently be used with fix rigid or fix rigid/small Self-explanatory. E: Cannot use fix gcmc in a 2d simulation Fix gcmc is set up to run in 3d only. No 2d simulations with fix gcmc are allowed. E: Could not find fix gcmc exclusion group ID Self-explanatory. E: Could not find fix gcmc rotation group ID Self-explanatory. E: Illegal fix gcmc gas mass <= 0 The computed mass of the designated gas molecule or atom type was less than or equal to zero. E: Cannot do GCMC on atoms in atom_modify first group This is a restriction due to the way atoms are organized in a list to enable the atom_modify first command. E: Could not find specified fix gcmc group ID Self-explanatory. E: Fix gcmc put atom outside box This should not normally happen. Contact the developers. E: Fix gcmc ran out of available molecule IDs See the setting for tagint in the src/lmptype.h file. E: Fix gcmc ran out of available atom IDs See the setting for tagint in the src/lmptype.h file. E: Too many total atoms See the setting for bigint in the src/lmptype.h file. */ diff --git a/src/MC/fix_tfmc.h b/src/MC/fix_tfmc.h index fee3a944c..d4f121eb9 100644 --- a/src/MC/fix_tfmc.h +++ b/src/MC/fix_tfmc.h @@ -1,76 +1,76 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(tfmc,FixTFMC) #else #ifndef LMP_FIX_TFMC_H #define LMP_FIX_TFMC_H #include "fix.h" namespace LAMMPS_NS { class FixTFMC : public Fix { public: FixTFMC(class LAMMPS *, int, char **); ~FixTFMC(); int setmask(); void init(); void initial_integrate(int); private: double d_max; double T_set; double mass_min; double **xd; int mass_require; int seed; int comflag, rotflag, xflag, yflag, zflag; int nmax; class RanMars *random_num; }; } #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 tfmc displacement length must be > 0 Self-explanatory. E: Fix tfmc temperature must be > 0 Self-explanatory. E: Illegal fix tfmc random seed Seeds can only be nonzero positive integers. E: Fix tfmc is not compatible with fix shake These two commands cannot currently be used together. */ diff --git a/src/MOLECULE/dihedral_charmm.cpp b/src/MOLECULE/dihedral_charmm.cpp index b9d1c440d..35953a6ac 100644 --- a/src/MOLECULE/dihedral_charmm.cpp +++ b/src/MOLECULE/dihedral_charmm.cpp @@ -1,439 +1,457 @@ /* ---------------------------------------------------------------------- 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 #include #include +#include #include "dihedral_charmm.h" #include "atom.h" #include "comm.h" #include "neighbor.h" #include "domain.h" #include "force.h" #include "pair.h" #include "update.h" +#include "respa.h" #include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; using namespace MathConst; #define TOLERANCE 0.05 /* ---------------------------------------------------------------------- */ DihedralCharmm::DihedralCharmm(LAMMPS *lmp) : Dihedral(lmp) { weightflag = 0; writedata = 1; } /* ---------------------------------------------------------------------- */ DihedralCharmm::~DihedralCharmm() { if (allocated && !copymode) { memory->destroy(setflag); memory->destroy(k); memory->destroy(multiplicity); memory->destroy(shift); memory->destroy(cos_shift); memory->destroy(sin_shift); memory->destroy(weight); } } /* ---------------------------------------------------------------------- */ void DihedralCharmm::compute(int eflag, int vflag) { int i1,i2,i3,i4,i,m,n,type; double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm; double edihedral,f1[3],f2[3],f3[3],f4[3]; double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv; double df,df1,ddf1,fg,hg,fga,hgb,gaa,gbb; double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz; double c,s,p,sx2,sy2,sz2; int itype,jtype; double delx,dely,delz,rsq,r2inv,r6inv; double forcecoul,forcelj,fpair,ecoul,evdwl; edihedral = evdwl = ecoul = 0.0; 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; double **x = atom->x; double **f = atom->f; double *q = atom->q; int *atomtype = atom->type; int **dihedrallist = neighbor->dihedrallist; int ndihedrallist = neighbor->ndihedrallist; int nlocal = atom->nlocal; int newton_bond = force->newton_bond; double qqrd2e = force->qqrd2e; for (n = 0; n < ndihedrallist; n++) { i1 = dihedrallist[n][0]; i2 = dihedrallist[n][1]; i3 = dihedrallist[n][2]; i4 = dihedrallist[n][3]; type = dihedrallist[n][4]; // 1st bond vb1x = x[i1][0] - x[i2][0]; vb1y = x[i1][1] - x[i2][1]; vb1z = x[i1][2] - x[i2][2]; // 2nd bond vb2x = x[i3][0] - x[i2][0]; vb2y = x[i3][1] - x[i2][1]; vb2z = x[i3][2] - x[i2][2]; vb2xm = -vb2x; vb2ym = -vb2y; vb2zm = -vb2z; // 3rd bond vb3x = x[i4][0] - x[i3][0]; vb3y = x[i4][1] - x[i3][1]; vb3z = x[i4][2] - x[i3][2]; ax = vb1y*vb2zm - vb1z*vb2ym; ay = vb1z*vb2xm - vb1x*vb2zm; az = vb1x*vb2ym - vb1y*vb2xm; bx = vb3y*vb2zm - vb3z*vb2ym; by = vb3z*vb2xm - vb3x*vb2zm; bz = vb3x*vb2ym - vb3y*vb2xm; rasq = ax*ax + ay*ay + az*az; rbsq = bx*bx + by*by + bz*bz; rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm; rg = sqrt(rgsq); rginv = ra2inv = rb2inv = 0.0; if (rg > 0) rginv = 1.0/rg; if (rasq > 0) ra2inv = 1.0/rasq; if (rbsq > 0) rb2inv = 1.0/rbsq; rabinv = sqrt(ra2inv*rb2inv); c = (ax*bx + ay*by + az*bz)*rabinv; s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z); // error check if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) { int me; MPI_Comm_rank(world,&me); if (screen) { char str[128]; sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, me,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][0],x[i1][1],x[i1][2]); fprintf(screen," 2nd atom: %d %g %g %g\n", me,x[i2][0],x[i2][1],x[i2][2]); fprintf(screen," 3rd atom: %d %g %g %g\n", me,x[i3][0],x[i3][1],x[i3][2]); fprintf(screen," 4th atom: %d %g %g %g\n", me,x[i4][0],x[i4][1],x[i4][2]); } } if (c > 1.0) c = 1.0; if (c < -1.0) c = -1.0; m = multiplicity[type]; p = 1.0; ddf1 = df1 = 0.0; for (i = 0; i < m; i++) { ddf1 = p*c - df1*s; df1 = p*s + df1*c; p = ddf1; } p = p*cos_shift[type] + df1*sin_shift[type]; df1 = df1*cos_shift[type] - ddf1*sin_shift[type]; df1 *= -m; p += 1.0; if (m == 0) { p = 1.0 + cos_shift[type]; df1 = 0.0; } if (eflag) edihedral = k[type] * p; fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm; hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm; fga = fg*ra2inv*rginv; hgb = hg*rb2inv*rginv; gaa = -ra2inv*rg; gbb = rb2inv*rg; dtfx = gaa*ax; dtfy = gaa*ay; dtfz = gaa*az; dtgx = fga*ax - hgb*bx; dtgy = fga*ay - hgb*by; dtgz = fga*az - hgb*bz; dthx = gbb*bx; dthy = gbb*by; dthz = gbb*bz; df = -k[type] * df1; sx2 = df*dtgx; sy2 = df*dtgy; sz2 = df*dtgz; f1[0] = df*dtfx; f1[1] = df*dtfy; f1[2] = df*dtfz; f2[0] = sx2 - f1[0]; f2[1] = sy2 - f1[1]; f2[2] = sz2 - f1[2]; f4[0] = df*dthx; f4[1] = df*dthy; f4[2] = df*dthz; f3[0] = -sx2 - f4[0]; f3[1] = -sy2 - f4[1]; f3[2] = -sz2 - f4[2]; // apply force to each of 4 atoms if (newton_bond || i1 < nlocal) { f[i1][0] += f1[0]; f[i1][1] += f1[1]; f[i1][2] += f1[2]; } if (newton_bond || i2 < nlocal) { f[i2][0] += f2[0]; f[i2][1] += f2[1]; f[i2][2] += f2[2]; } if (newton_bond || i3 < nlocal) { f[i3][0] += f3[0]; f[i3][1] += f3[1]; f[i3][2] += f3[2]; } if (newton_bond || i4 < nlocal) { f[i4][0] += f4[0]; f[i4][1] += f4[1]; f[i4][2] += f4[2]; } if (evflag) ev_tally(i1,i2,i3,i4,nlocal,newton_bond,edihedral,f1,f3,f4, vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z); // 1-4 LJ and Coulomb interactions // tally energy/virial in pair, using newton_bond as newton flag if (weight[type] > 0.0) { itype = atomtype[i1]; jtype = atomtype[i4]; delx = x[i1][0] - x[i4][0]; dely = x[i1][1] - x[i4][1]; delz = x[i1][2] - x[i4][2]; rsq = delx*delx + dely*dely + delz*delz; r2inv = 1.0/rsq; r6inv = r2inv*r2inv*r2inv; if (implicit) forcecoul = qqrd2e * q[i1]*q[i4]*r2inv; else forcecoul = qqrd2e * q[i1]*q[i4]*sqrt(r2inv); forcelj = r6inv * (lj14_1[itype][jtype]*r6inv - lj14_2[itype][jtype]); fpair = weight[type] * (forcelj+forcecoul)*r2inv; if (eflag) { ecoul = weight[type] * forcecoul; evdwl = r6inv * (lj14_3[itype][jtype]*r6inv - lj14_4[itype][jtype]); evdwl *= weight[type]; } if (newton_bond || i1 < nlocal) { f[i1][0] += delx*fpair; f[i1][1] += dely*fpair; f[i1][2] += delz*fpair; } if (newton_bond || i4 < nlocal) { f[i4][0] -= delx*fpair; f[i4][1] -= dely*fpair; f[i4][2] -= delz*fpair; } if (evflag) force->pair->ev_tally(i1,i4,nlocal,newton_bond, evdwl,ecoul,fpair,delx,dely,delz); } } } /* ---------------------------------------------------------------------- */ void DihedralCharmm::allocate() { allocated = 1; int n = atom->ndihedraltypes; memory->create(k,n+1,"dihedral:k"); memory->create(multiplicity,n+1,"dihedral:k"); memory->create(shift,n+1,"dihedral:shift"); memory->create(cos_shift,n+1,"dihedral:cos_shift"); memory->create(sin_shift,n+1,"dihedral:sin_shift"); memory->create(weight,n+1,"dihedral:weight"); memory->create(setflag,n+1,"dihedral:setflag"); for (int i = 1; i <= n; i++) setflag[i] = 0; } /* ---------------------------------------------------------------------- set coeffs for one type ------------------------------------------------------------------------- */ void DihedralCharmm::coeff(int narg, char **arg) { if (narg != 5) error->all(FLERR,"Incorrect args for dihedral coefficients"); if (!allocated) allocate(); int ilo,ihi; force->bounds(FLERR,arg[0],atom->ndihedraltypes,ilo,ihi); // require integer values of shift for backwards compatibility // arbitrary phase angle shift could be allowed, but would break // backwards compatibility and is probably not needed double k_one = force->numeric(FLERR,arg[1]); int multiplicity_one = force->inumeric(FLERR,arg[2]); int shift_one = force->inumeric(FLERR,arg[3]); double weight_one = force->numeric(FLERR,arg[4]); if (multiplicity_one < 0) error->all(FLERR,"Incorrect multiplicity arg for dihedral coefficients"); if (weight_one < 0.0 || weight_one > 1.0) error->all(FLERR,"Incorrect weight arg for dihedral coefficients"); if (weight_one > 0.0) weightflag=1; int count = 0; for (int i = ilo; i <= ihi; i++) { k[i] = k_one; shift[i] = shift_one; cos_shift[i] = cos(MY_PI*shift_one/180.0); sin_shift[i] = sin(MY_PI*shift_one/180.0); multiplicity[i] = multiplicity_one; weight[i] = weight_one; setflag[i] = 1; count++; } if (count == 0) error->all(FLERR,"Incorrect args for dihedral coefficients"); } /* ---------------------------------------------------------------------- error check and initialize all values needed for force computation ------------------------------------------------------------------------- */ void DihedralCharmm::init_style() { + if (strstr(update->integrate_style,"respa")) { + Respa *r = (Respa *) update->integrate; + if (r->level_pair >= 0 && (r->level_pair != r->level_dihedral)) + error->all(FLERR,"Dihedral style charmm must be set to same" + " r-RESPA level as 'pair'"); + if (r->level_outer >= 0 && (r->level_outer != r->level_dihedral)) + error->all(FLERR,"Dihedral style charmm must be set to same" + " r-RESPA level as 'outer'"); + } + // insure use of CHARMM pair_style if any weight factors are non-zero // set local ptrs to LJ 14 arrays setup by Pair + // also verify that the correct 1-4 scaling is set if (weightflag) { + + if ((force->special_lj[3] != 0.0) || (force->special_coul[3] != 0.0)) + error->all(FLERR,"Must use 'special_bonds charmm' with" + " dihedral style charmm for use with CHARMM pair styles"); + int itmp; if (force->pair == NULL) error->all(FLERR,"Dihedral charmm is incompatible with Pair style"); lj14_1 = (double **) force->pair->extract("lj14_1",itmp); lj14_2 = (double **) force->pair->extract("lj14_2",itmp); lj14_3 = (double **) force->pair->extract("lj14_3",itmp); lj14_4 = (double **) force->pair->extract("lj14_4",itmp); int *ptr = (int *) force->pair->extract("implicit",itmp); if (!lj14_1 || !lj14_2 || !lj14_3 || !lj14_4 || !ptr) error->all(FLERR,"Dihedral charmm is incompatible with Pair style"); implicit = *ptr; } } /* ---------------------------------------------------------------------- proc 0 writes out coeffs to restart file ------------------------------------------------------------------------- */ void DihedralCharmm::write_restart(FILE *fp) { fwrite(&k[1],sizeof(double),atom->ndihedraltypes,fp); fwrite(&multiplicity[1],sizeof(int),atom->ndihedraltypes,fp); fwrite(&shift[1],sizeof(int),atom->ndihedraltypes,fp); fwrite(&weight[1],sizeof(double),atom->ndihedraltypes,fp); fwrite(&weightflag,sizeof(int),1,fp); } /* ---------------------------------------------------------------------- proc 0 reads coeffs from restart file, bcasts them ------------------------------------------------------------------------- */ void DihedralCharmm::read_restart(FILE *fp) { allocate(); if (comm->me == 0) { fread(&k[1],sizeof(double),atom->ndihedraltypes,fp); fread(&multiplicity[1],sizeof(int),atom->ndihedraltypes,fp); fread(&shift[1],sizeof(int),atom->ndihedraltypes,fp); fread(&weight[1],sizeof(double),atom->ndihedraltypes,fp); fread(&weightflag,sizeof(int),1,fp); } MPI_Bcast(&k[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); MPI_Bcast(&multiplicity[1],atom->ndihedraltypes,MPI_INT,0,world); MPI_Bcast(&shift[1],atom->ndihedraltypes,MPI_INT,0,world); MPI_Bcast(&weight[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); MPI_Bcast(&weightflag,1,MPI_INT,0,world); for (int i = 1; i <= atom->ndihedraltypes; i++) { setflag[i] = 1; cos_shift[i] = cos(MY_PI*shift[i]/180.0); sin_shift[i] = sin(MY_PI*shift[i]/180.0); } } /* ---------------------------------------------------------------------- proc 0 writes to data file ------------------------------------------------------------------------- */ void DihedralCharmm::write_data(FILE *fp) { for (int i = 1; i <= atom->ndihedraltypes; i++) fprintf(fp,"%d %g %d %d %g\n",i,k[i],multiplicity[i],shift[i],weight[i]); } diff --git a/src/MOLECULE/dihedral_charmmfsw.cpp b/src/MOLECULE/dihedral_charmmfsw.cpp index 613170bbf..feb3e02bd 100644 --- a/src/MOLECULE/dihedral_charmmfsw.cpp +++ b/src/MOLECULE/dihedral_charmmfsw.cpp @@ -1,482 +1,500 @@ /* ---------------------------------------------------------------------- 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) The force-shifted sections were provided by Robert Meissner and Lucio Colombi Ciacchi of Bremen University, Bremen, Germany, with additional assistance from Robert A. Latour, Clemson University ------------------------------------------------------------------------- */ #include #include #include +#include #include "dihedral_charmmfsw.h" #include "atom.h" #include "comm.h" #include "neighbor.h" #include "domain.h" #include "force.h" #include "pair.h" #include "update.h" +#include "respa.h" #include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; using namespace MathConst; #define TOLERANCE 0.05 /* ---------------------------------------------------------------------- */ DihedralCharmmfsw::DihedralCharmmfsw(LAMMPS *lmp) : Dihedral(lmp) { weightflag = 0; writedata = 1; } /* ---------------------------------------------------------------------- */ DihedralCharmmfsw::~DihedralCharmmfsw() { if (allocated && !copymode) { memory->destroy(setflag); memory->destroy(k); memory->destroy(multiplicity); memory->destroy(shift); memory->destroy(cos_shift); memory->destroy(sin_shift); memory->destroy(weight); } } /* ---------------------------------------------------------------------- */ void DihedralCharmmfsw::compute(int eflag, int vflag) { int i1,i2,i3,i4,i,m,n,type; double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm; double edihedral,f1[3],f2[3],f3[3],f4[3]; double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv; double df,df1,ddf1,fg,hg,fga,hgb,gaa,gbb; double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz; double c,s,p,sx2,sy2,sz2; int itype,jtype; double delx,dely,delz,rsq,r2inv,r6inv,r; double forcecoul,forcelj,fpair,ecoul,evdwl; edihedral = evdwl = ecoul = 0.0; 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; double **x = atom->x; double **f = atom->f; double *q = atom->q; int *atomtype = atom->type; int **dihedrallist = neighbor->dihedrallist; int ndihedrallist = neighbor->ndihedrallist; int nlocal = atom->nlocal; int newton_bond = force->newton_bond; double qqrd2e = force->qqrd2e; for (n = 0; n < ndihedrallist; n++) { i1 = dihedrallist[n][0]; i2 = dihedrallist[n][1]; i3 = dihedrallist[n][2]; i4 = dihedrallist[n][3]; type = dihedrallist[n][4]; // 1st bond vb1x = x[i1][0] - x[i2][0]; vb1y = x[i1][1] - x[i2][1]; vb1z = x[i1][2] - x[i2][2]; // 2nd bond vb2x = x[i3][0] - x[i2][0]; vb2y = x[i3][1] - x[i2][1]; vb2z = x[i3][2] - x[i2][2]; vb2xm = -vb2x; vb2ym = -vb2y; vb2zm = -vb2z; // 3rd bond vb3x = x[i4][0] - x[i3][0]; vb3y = x[i4][1] - x[i3][1]; vb3z = x[i4][2] - x[i3][2]; ax = vb1y*vb2zm - vb1z*vb2ym; ay = vb1z*vb2xm - vb1x*vb2zm; az = vb1x*vb2ym - vb1y*vb2xm; bx = vb3y*vb2zm - vb3z*vb2ym; by = vb3z*vb2xm - vb3x*vb2zm; bz = vb3x*vb2ym - vb3y*vb2xm; rasq = ax*ax + ay*ay + az*az; rbsq = bx*bx + by*by + bz*bz; rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm; rg = sqrt(rgsq); rginv = ra2inv = rb2inv = 0.0; if (rg > 0) rginv = 1.0/rg; if (rasq > 0) ra2inv = 1.0/rasq; if (rbsq > 0) rb2inv = 1.0/rbsq; rabinv = sqrt(ra2inv*rb2inv); c = (ax*bx + ay*by + az*bz)*rabinv; s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z); // error check if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) { int me; MPI_Comm_rank(world,&me); if (screen) { char str[128]; sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, me,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][0],x[i1][1],x[i1][2]); fprintf(screen," 2nd atom: %d %g %g %g\n", me,x[i2][0],x[i2][1],x[i2][2]); fprintf(screen," 3rd atom: %d %g %g %g\n", me,x[i3][0],x[i3][1],x[i3][2]); fprintf(screen," 4th atom: %d %g %g %g\n", me,x[i4][0],x[i4][1],x[i4][2]); } } if (c > 1.0) c = 1.0; if (c < -1.0) c = -1.0; m = multiplicity[type]; p = 1.0; ddf1 = df1 = 0.0; for (i = 0; i < m; i++) { ddf1 = p*c - df1*s; df1 = p*s + df1*c; p = ddf1; } p = p*cos_shift[type] + df1*sin_shift[type]; df1 = df1*cos_shift[type] - ddf1*sin_shift[type]; df1 *= -m; p += 1.0; if (m == 0) { p = 1.0 + cos_shift[type]; df1 = 0.0; } if (eflag) edihedral = k[type] * p; fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm; hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm; fga = fg*ra2inv*rginv; hgb = hg*rb2inv*rginv; gaa = -ra2inv*rg; gbb = rb2inv*rg; dtfx = gaa*ax; dtfy = gaa*ay; dtfz = gaa*az; dtgx = fga*ax - hgb*bx; dtgy = fga*ay - hgb*by; dtgz = fga*az - hgb*bz; dthx = gbb*bx; dthy = gbb*by; dthz = gbb*bz; df = -k[type] * df1; sx2 = df*dtgx; sy2 = df*dtgy; sz2 = df*dtgz; f1[0] = df*dtfx; f1[1] = df*dtfy; f1[2] = df*dtfz; f2[0] = sx2 - f1[0]; f2[1] = sy2 - f1[1]; f2[2] = sz2 - f1[2]; f4[0] = df*dthx; f4[1] = df*dthy; f4[2] = df*dthz; f3[0] = -sx2 - f4[0]; f3[1] = -sy2 - f4[1]; f3[2] = -sz2 - f4[2]; // apply force to each of 4 atoms if (newton_bond || i1 < nlocal) { f[i1][0] += f1[0]; f[i1][1] += f1[1]; f[i1][2] += f1[2]; } if (newton_bond || i2 < nlocal) { f[i2][0] += f2[0]; f[i2][1] += f2[1]; f[i2][2] += f2[2]; } if (newton_bond || i3 < nlocal) { f[i3][0] += f3[0]; f[i3][1] += f3[1]; f[i3][2] += f3[2]; } if (newton_bond || i4 < nlocal) { f[i4][0] += f4[0]; f[i4][1] += f4[1]; f[i4][2] += f4[2]; } if (evflag) ev_tally(i1,i2,i3,i4,nlocal,newton_bond,edihedral,f1,f3,f4, vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z); // 1-4 LJ and Coulomb interactions // tally energy/virial in pair, using newton_bond as newton flag if (weight[type] > 0.0) { itype = atomtype[i1]; jtype = atomtype[i4]; delx = x[i1][0] - x[i4][0]; dely = x[i1][1] - x[i4][1]; delz = x[i1][2] - x[i4][2]; rsq = delx*delx + dely*dely + delz*delz; r2inv = 1.0/rsq; r6inv = r2inv*r2inv*r2inv; // modifying coul and LJ force and energies to apply // force_shift and force_switch as in CHARMM pairwise // LJ interactions between 1-4 atoms should usually be // for r < cut_inner, so switching not applied r = sqrt(rsq); if (implicit) forcecoul = qqrd2e * q[i1]*q[i4]*r2inv; else if (dihedflag) forcecoul = qqrd2e * q[i1]*q[i4]*sqrt(r2inv); else forcecoul = qqrd2e * q[i1]*q[i4]*(sqrt(r2inv) - r*cut_coulinv14*cut_coulinv14); forcelj = r6inv * (lj14_1[itype][jtype]*r6inv - lj14_2[itype][jtype]); fpair = weight[type] * (forcelj+forcecoul)*r2inv; if (eflag) { if (dihedflag) ecoul = weight[type] * forcecoul; else ecoul = weight[type] * qqrd2e * q[i1]*q[i4] * (sqrt(r2inv) + r*cut_coulinv14*cut_coulinv14 - 2.0*cut_coulinv14); evdwl14_12 = r6inv*lj14_3[itype][jtype]*r6inv - lj14_3[itype][jtype]*cut_lj_inner6inv*cut_lj6inv; evdwl14_6 = -lj14_4[itype][jtype]*r6inv + lj14_4[itype][jtype]*cut_lj_inner3inv*cut_lj3inv; evdwl = evdwl14_12 + evdwl14_6; evdwl *= weight[type]; } if (newton_bond || i1 < nlocal) { f[i1][0] += delx*fpair; f[i1][1] += dely*fpair; f[i1][2] += delz*fpair; } if (newton_bond || i4 < nlocal) { f[i4][0] -= delx*fpair; f[i4][1] -= dely*fpair; f[i4][2] -= delz*fpair; } if (evflag) force->pair->ev_tally(i1,i4,nlocal,newton_bond, evdwl,ecoul,fpair,delx,dely,delz); } } } /* ---------------------------------------------------------------------- */ void DihedralCharmmfsw::allocate() { allocated = 1; int n = atom->ndihedraltypes; memory->create(k,n+1,"dihedral:k"); memory->create(multiplicity,n+1,"dihedral:k"); memory->create(shift,n+1,"dihedral:shift"); memory->create(cos_shift,n+1,"dihedral:cos_shift"); memory->create(sin_shift,n+1,"dihedral:sin_shift"); memory->create(weight,n+1,"dihedral:weight"); memory->create(setflag,n+1,"dihedral:setflag"); for (int i = 1; i <= n; i++) setflag[i] = 0; } /* ---------------------------------------------------------------------- set coeffs for one type ------------------------------------------------------------------------- */ void DihedralCharmmfsw::coeff(int narg, char **arg) { if (narg != 5) error->all(FLERR,"Incorrect args for dihedral coefficients"); if (!allocated) allocate(); int ilo,ihi; force->bounds(FLERR,arg[0],atom->ndihedraltypes,ilo,ihi); // require integer values of shift for backwards compatibility // arbitrary phase angle shift could be allowed, but would break // backwards compatibility and is probably not needed double k_one = force->numeric(FLERR,arg[1]); int multiplicity_one = force->inumeric(FLERR,arg[2]); int shift_one = force->inumeric(FLERR,arg[3]); double weight_one = force->numeric(FLERR,arg[4]); if (multiplicity_one < 0) error->all(FLERR,"Incorrect multiplicity arg for dihedral coefficients"); if (weight_one < 0.0 || weight_one > 1.0) error->all(FLERR,"Incorrect weight arg for dihedral coefficients"); if (weight_one > 0.0) weightflag=1; int count = 0; for (int i = ilo; i <= ihi; i++) { k[i] = k_one; shift[i] = shift_one; cos_shift[i] = cos(MY_PI*shift_one/180.0); sin_shift[i] = sin(MY_PI*shift_one/180.0); multiplicity[i] = multiplicity_one; weight[i] = weight_one; setflag[i] = 1; count++; } if (count == 0) error->all(FLERR,"Incorrect args for dihedral coefficients"); } /* ---------------------------------------------------------------------- error check and initialize all values needed for force computation ------------------------------------------------------------------------- */ void DihedralCharmmfsw::init_style() { + if (strstr(update->integrate_style,"respa")) { + Respa *r = (Respa *) update->integrate; + if (r->level_pair >= 0 && (r->level_pair != r->level_dihedral)) + error->all(FLERR,"Dihedral style charmmfsw must be set to same" + " r-RESPA level as 'pair'"); + if (r->level_outer >= 0 && (r->level_outer != r->level_dihedral)) + error->all(FLERR,"Dihedral style charmmfsw must be set to same" + " r-RESPA level as 'outer'"); + } + // insure use of CHARMM pair_style if any weight factors are non-zero // set local ptrs to LJ 14 arrays setup by Pair + // also verify that the correct 1-4 scaling is set if (weightflag) { + + if ((force->special_lj[3] != 0.0) || (force->special_coul[3] != 0.0)) + error->all(FLERR,"Must use 'special_bonds charmm' with" + " dihedral style charmm for use with CHARMM pair styles"); + int itmp; if (force->pair == NULL) error->all(FLERR,"Dihedral charmmfsw is incompatible with Pair style"); lj14_1 = (double **) force->pair->extract("lj14_1",itmp); lj14_2 = (double **) force->pair->extract("lj14_2",itmp); lj14_3 = (double **) force->pair->extract("lj14_3",itmp); lj14_4 = (double **) force->pair->extract("lj14_4",itmp); int *ptr = (int *) force->pair->extract("implicit",itmp); if (!lj14_1 || !lj14_2 || !lj14_3 || !lj14_4 || !ptr) error->all(FLERR,"Dihedral charmmfsw is incompatible with Pair style"); implicit = *ptr; } // constants for applying force switch (LJ) and force_shift (coul) // to 1/4 dihedral atoms to match CHARMM pairwise interactions int itmp; int *p_dihedflag = (int *) force->pair->extract("dihedflag",itmp); double *p_cutljinner = (double *) force->pair->extract("cut_lj_inner",itmp); double *p_cutlj = (double *) force->pair->extract("cut_lj",itmp); double *p_cutcoul = (double *) force->pair->extract("cut_coul",itmp); if (p_cutcoul == NULL || p_cutljinner == NULL || p_cutlj == NULL || p_dihedflag == NULL) error->all(FLERR,"Dihedral charmmfsw is incompatible with Pair style"); dihedflag = *p_dihedflag; cut_coul14 = *p_cutcoul; cut_lj_inner14 = *p_cutljinner; cut_lj14 = *p_cutlj; cut_coulinv14 = 1/cut_coul14; cut_lj_inner3inv = (1/cut_lj_inner14) * (1/cut_lj_inner14) * (1/cut_lj_inner14); cut_lj_inner6inv = cut_lj_inner3inv * cut_lj_inner3inv; cut_lj3inv = (1/cut_lj14) * (1/cut_lj14) * (1/cut_lj14); cut_lj6inv = cut_lj3inv * cut_lj3inv; } /* ---------------------------------------------------------------------- proc 0 writes out coeffs to restart file ------------------------------------------------------------------------- */ void DihedralCharmmfsw::write_restart(FILE *fp) { fwrite(&k[1],sizeof(double),atom->ndihedraltypes,fp); fwrite(&multiplicity[1],sizeof(int),atom->ndihedraltypes,fp); fwrite(&shift[1],sizeof(int),atom->ndihedraltypes,fp); fwrite(&weight[1],sizeof(double),atom->ndihedraltypes,fp); fwrite(&weightflag,sizeof(int),1,fp); } /* ---------------------------------------------------------------------- proc 0 reads coeffs from restart file, bcasts them ------------------------------------------------------------------------- */ void DihedralCharmmfsw::read_restart(FILE *fp) { allocate(); if (comm->me == 0) { fread(&k[1],sizeof(double),atom->ndihedraltypes,fp); fread(&multiplicity[1],sizeof(int),atom->ndihedraltypes,fp); fread(&shift[1],sizeof(int),atom->ndihedraltypes,fp); fread(&weight[1],sizeof(double),atom->ndihedraltypes,fp); fread(&weightflag,sizeof(int),1,fp); } MPI_Bcast(&k[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); MPI_Bcast(&multiplicity[1],atom->ndihedraltypes,MPI_INT,0,world); MPI_Bcast(&shift[1],atom->ndihedraltypes,MPI_INT,0,world); MPI_Bcast(&weight[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); MPI_Bcast(&weightflag,1,MPI_INT,0,world); for (int i = 1; i <= atom->ndihedraltypes; i++) { setflag[i] = 1; cos_shift[i] = cos(MY_PI*shift[i]/180.0); sin_shift[i] = sin(MY_PI*shift[i]/180.0); } } /* ---------------------------------------------------------------------- proc 0 writes to data file ------------------------------------------------------------------------- */ void DihedralCharmmfsw::write_data(FILE *fp) { for (int i = 1; i <= atom->ndihedraltypes; i++) fprintf(fp,"%d %g %d %d %g\n",i,k[i],multiplicity[i],shift[i],weight[i]); } diff --git a/src/RIGID/fix_ehex.h b/src/RIGID/fix_ehex.h index 3220b7719..02f83df1a 100644 --- a/src/RIGID/fix_ehex.h +++ b/src/RIGID/fix_ehex.h @@ -1,130 +1,130 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(ehex,FixEHEX) #else #ifndef LMP_FIX_EHEX_H #define LMP_FIX_EHEX_H #include "fix.h" #include "fix_shake.h" #include "region.h" #define EHEX_DEBUG 0 namespace LAMMPS_NS { class FixEHEX : public Fix { public: FixEHEX(class LAMMPS *, int, char **); ~FixEHEX(); int setmask(); void init(); void end_of_step(); void rescale(); double compute_scalar(); double memory_usage(); void update_scalingmask(); void com_properties(double *, double *, double *, double*, double *, double*); bool rescale_atom(int i, Region*region); virtual void grow_arrays(int nmax); bool check_cluster(tagint *shake_atom, int n, Region * region); private: int iregion; double heat_input; double masstotal; double scale; char *idregion; int me; double **x; // coordinates double **f; // forces double **v; // velocities double *mass; // masses double *rmass; // reduced masses int *type; // atom types int nlocal; // number of local atoms FixShake * fshake; // pointer to fix_shake/fix_rattle int constraints; // constraints (0/1) int cluster; // rescaling entire clusters (0/1) int hex; // HEX mode (0/1) bool *scalingmask; // scalingmask[i] determines whether // the velocity of atom i is to be rescaled }; } #endif #endif /* ERROR/WARNING messages: E: Illegal fix ehex command: wrong number of parameters 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: Illegal fix ehex command: integer value expected Self-explanatory. Check the value for nevery. E: Region ID for fix ehex does not exist Self-explanatory. E: You can only use the keyword 'com' together with the keyword 'constrain' . Self-explanatory. E: Illegal fix ehex keyword Self-explanatory. E: Fix ehex group has no atoms Self-explanatory. E: Multiple instances of fix shake/rattle detected (not supported yet) You can only have one instance of fix rattle/shake at the moment. E: Fix ehex was configured with keyword constrain, but shake/rattle was not defined The option constrain requires either fix shake or fix rattle which is missing in the input script. E: Fix heat kinetic energy went negative This will cause the velocity rescaling about to be performed by fix heat to be invalid. E: Fix heat kinetic energy of an atom went negative This will cause the velocity rescaling about to be performed by fix heat to be invalid. E: Internal error: shake_flag[m] has to be between 1 and 4 for m in nlist Contact developers. E: Fix ehex error mass of region is close to zero Check your configuration. */ diff --git a/src/USER-CGDNA/mf_oxdna.h b/src/USER-CGDNA/mf_oxdna.h index 642c325af..56055d5fa 100644 --- a/src/USER-CGDNA/mf_oxdna.h +++ b/src/USER-CGDNA/mf_oxdna.h @@ -1,288 +1,288 @@ -/* ---------------------------------------------------------------------- +/* -*- 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 MF_OXDNA_H #define MF_OXDNA_H #include #include "math_extra.h" namespace MFOxdna { inline double F1(double, double, double, double, double, double, double, double, double, double, double); inline double DF1(double, double, double, double, double, double, double, double, double, double); inline double F2(double, double, double, double, double, double, double, double, double, double); inline double DF2(double, double, double, double, double, double, double, double, double); inline double F3(double, double, double, double, double, double, double, double &); inline double F4(double, double, double, double, double, double); inline double DF4(double, double, double, double, double, double); inline double F5(double, double, double, double, double); inline double DF5(double, double, double, double, double); inline double F6(double, double, double); inline double DF6(double, double, double); inline double is_3pto5p(const double *, const double *); } /* ---------------------------------------------------------------------- f1 modulation factor ------------------------------------------------------------------------- */ inline double MFOxdna::F1(double r, double eps, double a, double cut_0, double cut_lc, double cut_hc, double cut_lo, double cut_hi, double b_lo, double b_hi, double shift) { if (r > cut_hc) { return 0.0; } else if (r > cut_hi) { return eps * b_hi * (r-cut_hc) * (r-cut_hc); } else if (r > cut_lo) { double tmp = 1 - exp(-(r-cut_0) * a); return eps * tmp * tmp - shift; } else if (r > cut_lc) { return eps * b_lo * (r-cut_lc) * (r-cut_lc); } else { return 0.0; } } /* ---------------------------------------------------------------------- derivative of f1 modulation factor ------------------------------------------------------------------------- */ inline double MFOxdna::DF1(double r, double eps, double a, double cut_0, double cut_lc, double cut_hc, double cut_lo, double cut_hi, double b_lo, double b_hi) { if (r > cut_hc) { return 0.0; } else if (r > cut_hi) { return 2 * eps * b_hi * (1 - cut_hc / r); } else if (r > cut_lo) { double tmp = exp(-(r-cut_0) * a); return 2 * eps * (1 - tmp) * tmp * a / r; } else if (r > cut_lc) { return 2 * eps * b_lo * (1 - cut_lc / r); } else { return 0.0; } } /* ---------------------------------------------------------------------- f2 modulation factor ------------------------------------------------------------------------- */ inline double MFOxdna::F2(double r, double k, double cut_0, double cut_lc, double cut_hc, double cut_lo, double cut_hi, double b_lo, double b_hi, double cut_c) { if(r < cut_lc || r > cut_hc){ return 0; } else if(r < cut_lo){ return k * b_lo * (cut_lc - r)*(cut_lc-r); } else if(r < cut_hi){ return k * 0.5 * ((r - cut_0)*(r-cut_0) - (cut_0 - cut_c)*(cut_0 - cut_c)); } else{ return k * b_hi * (cut_hc - r) * (cut_hc - r); } } /* ---------------------------------------------------------------------- derivative of f2 modulation factor ------------------------------------------------------------------------- */ inline double MFOxdna::DF2(double r, double k, double cut_0, double cut_lc, double cut_hc, double cut_lo, double cut_hi, double b_lo, double b_hi) { if(r < cut_lc || r > cut_hc){ return 0; } else if(r < cut_lo){ return 2*k * b_lo * (r - cut_lc); } else if(r < cut_hi){ return k * (r - cut_0); } else{ return 2*k * b_hi * (r - cut_hc); } } /* ---------------------------------------------------------------------- f3 modulation factor, force and energy calculation ------------------------------------------------------------------------- */ inline double MFOxdna::F3(double rsq, double cutsq_ast, double cut_c, double lj1, double lj2, double eps, double b, double & fpair) { double evdwl = 0.0; if (rsq < cutsq_ast) { double r2inv = 1.0/rsq; double r6inv = r2inv*r2inv*r2inv; fpair = r2inv*r6inv*(12*lj1*r6inv - 6*lj2); evdwl = r6inv*(lj1*r6inv-lj2); } else { double r = sqrt(rsq); double rinv = 1.0/r; fpair = 2*eps*b*(cut_c*rinv - 1); evdwl = eps*b*(cut_c-r)*(cut_c-r); } return evdwl; } /* ---------------------------------------------------------------------- f4 modulation factor ------------------------------------------------------------------------- */ inline double MFOxdna::F4(double theta, double a, double theta_0, double dtheta_ast, double b, double dtheta_c) { double dtheta = theta-theta_0; if (fabs(dtheta) > dtheta_c) { return 0.0; } else if (dtheta > dtheta_ast) { return b * (dtheta-dtheta_c)*(dtheta-dtheta_c); } else if(dtheta > -dtheta_ast) { return 1 - a * dtheta*dtheta; } else { return b * (dtheta+dtheta_c)*(dtheta+dtheta_c); } } /* ---------------------------------------------------------------------- derivative of f4 modulation factor NOTE: We handle the sin(theta) factor from the partial derivative of d(cos(theta))/dtheta externally. The reason for this is because the sign of DF4 depends on the sign of theta in the function call. It is also more efficient to store sin(theta). ------------------------------------------------------------------------- */ inline double MFOxdna::DF4(double theta, double a, double theta_0, double dtheta_ast, double b, double dtheta_c) { double dtheta = theta-theta_0; if (fabs(dtheta) > dtheta_c) { return 0.0; } else if (dtheta > dtheta_ast) { return 2*b* (dtheta-dtheta_c); } else if (dtheta > -dtheta_ast) { return -2*a * dtheta; } else { return 2*b* (dtheta+dtheta_c); } } /* ---------------------------------------------------------------------- f5 modulation factor ------------------------------------------------------------------------- */ inline double MFOxdna::F5(double x, double a, double x_ast, double b, double x_c) { if (x >= 0) { return 1.0; } else if (x > x_ast) { return 1 - a * x * x; } else if (x > x_c) { return b * (x-x_c) * (x-x_c); } else { return 0.0; } } /* ---------------------------------------------------------------------- derivative of f5 modulation factor ------------------------------------------------------------------------- */ inline double MFOxdna::DF5(double x, double a, double x_ast, double b, double x_c) { if(x >= 0) { return 0.0; } else if (x > x_ast) { return -2 * a * x; } else if(x > x_c) { return 2 * b * (x-x_c); } else { return 0.0; } return 0; } /* ---------------------------------------------------------------------- f6 modulation factor ------------------------------------------------------------------------- */ inline double MFOxdna::F6(double theta, double a, double b) { if (theta < b) { return 0.0; } else { return 0.5 * a * (theta-b)*(theta-b); } } /* ---------------------------------------------------------------------- derivative of f6 modulation factor ------------------------------------------------------------------------- */ inline double MFOxdna::DF6(double theta, double a, double b) { if (theta < b) { return 0.0; } else { return a * (theta-b); } } /* ---------------------------------------------------------------------- test for directionality by projecting base normal n onto delr = a - b, returns 1 if nucleotide b to nucleotide a is 3' to 5', otherwise -1 ------------------------------------------------------------------------- */ inline double MFOxdna::is_3pto5p(const double * delr, const double * n) { return copysign(1.0,MathExtra::dot3(delr,n)); } #endif diff --git a/src/USER-CGDNA/pair_oxdna2_coaxstk.h b/src/USER-CGDNA/pair_oxdna2_coaxstk.h index 477b35ee1..be8d6d6b3 100644 --- a/src/USER-CGDNA/pair_oxdna2_coaxstk.h +++ b/src/USER-CGDNA/pair_oxdna2_coaxstk.h @@ -1,85 +1,85 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(oxdna2/coaxstk,PairOxdna2Coaxstk) #else #ifndef LMP_PAIR_OXDNA2_COAXSTK_H #define LMP_PAIR_OXDNA2_COAXSTK_H #include "pair.h" namespace LAMMPS_NS { class PairOxdna2Coaxstk : public Pair { public: PairOxdna2Coaxstk(class LAMMPS *); virtual ~PairOxdna2Coaxstk(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); void init_list(int, class NeighList *); double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); void write_restart_settings(FILE *); void read_restart_settings(FILE *); void write_data(FILE *); void write_data_all(FILE *); void *extract(const char *, int &); protected: // coaxial stacking interaction double **k_cxst, **cut_cxst_0, **cut_cxst_c, **cut_cxst_lo, **cut_cxst_hi; double **cut_cxst_lc, **cut_cxst_hc, **b_cxst_lo, **b_cxst_hi; double **cutsq_cxst_hc; double **a_cxst1, **theta_cxst1_0, **dtheta_cxst1_ast; double **b_cxst1, **dtheta_cxst1_c; double **a_cxst4, **theta_cxst4_0, **dtheta_cxst4_ast; double **b_cxst4, **dtheta_cxst4_c; double **a_cxst5, **theta_cxst5_0, **dtheta_cxst5_ast; double **b_cxst5, **dtheta_cxst5_c; double **a_cxst6, **theta_cxst6_0, **dtheta_cxst6_ast; double **b_cxst6, **dtheta_cxst6_c; double **AA_cxst1, **BB_cxst1; virtual void allocate(); }; } #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. */ diff --git a/src/USER-CGDNA/pair_oxdna2_dh.h b/src/USER-CGDNA/pair_oxdna2_dh.h index 3af355d50..b40346e1c 100644 --- a/src/USER-CGDNA/pair_oxdna2_dh.h +++ b/src/USER-CGDNA/pair_oxdna2_dh.h @@ -1,72 +1,72 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(oxdna2/dh,PairOxdna2Dh) #else #ifndef LMP_PAIR_OXDNA2_DH_H #define LMP_PAIR_OXDNA2_DH_H #include "pair.h" namespace LAMMPS_NS { class PairOxdna2Dh : public Pair { public: PairOxdna2Dh(class LAMMPS *); virtual ~PairOxdna2Dh(); virtual void compute_interaction_sites(double *, double *, double *); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); void init_list(int, class NeighList *); double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); void write_restart_settings(FILE *); void read_restart_settings(FILE *); void write_data(FILE *); void write_data_all(FILE *); void *extract(const char *, int &); protected: double **qeff_dh_pf,**kappa_dh; double **b_dh,**cut_dh_ast,**cutsq_dh_ast,**cut_dh_c,**cutsq_dh_c; virtual void allocate(); }; } #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. */ diff --git a/src/USER-CGDNA/pair_oxdna2_excv.h b/src/USER-CGDNA/pair_oxdna2_excv.h index 94e39a0fa..f59daf836 100644 --- a/src/USER-CGDNA/pair_oxdna2_excv.h +++ b/src/USER-CGDNA/pair_oxdna2_excv.h @@ -1,52 +1,52 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(oxdna2/excv,PairOxdna2Excv) #else #ifndef LMP_PAIR_OXDNA2_EXCV_H #define LMP_PAIR_OXDNA2_EXCV_H #include "pair_oxdna_excv.h" namespace LAMMPS_NS { class PairOxdna2Excv : public PairOxdnaExcv { public: PairOxdna2Excv(class LAMMPS *); virtual ~PairOxdna2Excv(); virtual void compute_interaction_sites(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: Incorrect args for pair coefficients Self-explanatory. Check the input script or data file. */ diff --git a/src/USER-CGDNA/pair_oxdna2_stk.h b/src/USER-CGDNA/pair_oxdna2_stk.h index b78fc89d5..7654e5db2 100644 --- a/src/USER-CGDNA/pair_oxdna2_stk.h +++ b/src/USER-CGDNA/pair_oxdna2_stk.h @@ -1,53 +1,53 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(oxdna2/stk,PairOxdna2Stk) #else #ifndef LMP_PAIR_OXDNA2_STK_H #define LMP_PAIR_OXDNA2_STK_H #include "pair_oxdna_stk.h" namespace LAMMPS_NS { class PairOxdna2Stk : public PairOxdnaStk { public: PairOxdna2Stk(class LAMMPS *); virtual ~PairOxdna2Stk(); protected: virtual double stacking_strength(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: Incorrect args for pair coefficients Self-explanatory. Check the input script or data file. */ diff --git a/src/USER-CGDNA/pair_oxdna_coaxstk.h b/src/USER-CGDNA/pair_oxdna_coaxstk.h index b12ef6e77..f9228c94a 100644 --- a/src/USER-CGDNA/pair_oxdna_coaxstk.h +++ b/src/USER-CGDNA/pair_oxdna_coaxstk.h @@ -1,86 +1,86 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(oxdna/coaxstk,PairOxdnaCoaxstk) #else #ifndef LMP_PAIR_OXDNA_COAXSTK_H #define LMP_PAIR_OXDNA_COAXSTK_H #include "pair.h" namespace LAMMPS_NS { class PairOxdnaCoaxstk : public Pair { public: PairOxdnaCoaxstk(class LAMMPS *); virtual ~PairOxdnaCoaxstk(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); void init_list(int, class NeighList *); double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); void write_restart_settings(FILE *); void read_restart_settings(FILE *); void write_data(FILE *); void write_data_all(FILE *); void *extract(const char *, int &); protected: // coaxial stacking interaction double **k_cxst, **cut_cxst_0, **cut_cxst_c, **cut_cxst_lo, **cut_cxst_hi; double **cut_cxst_lc, **cut_cxst_hc, **b_cxst_lo, **b_cxst_hi; double **cutsq_cxst_hc; double **a_cxst1, **theta_cxst1_0, **dtheta_cxst1_ast; double **b_cxst1, **dtheta_cxst1_c; double **a_cxst4, **theta_cxst4_0, **dtheta_cxst4_ast; double **b_cxst4, **dtheta_cxst4_c; double **a_cxst5, **theta_cxst5_0, **dtheta_cxst5_ast; double **b_cxst5, **dtheta_cxst5_c; double **a_cxst6, **theta_cxst6_0, **dtheta_cxst6_ast; double **b_cxst6, **dtheta_cxst6_c; double **a_cxst3p, **cosphi_cxst3p_ast, **b_cxst3p, **cosphi_cxst3p_c; double **a_cxst4p, **cosphi_cxst4p_ast, **b_cxst4p, **cosphi_cxst4p_c; virtual void allocate(); }; } #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. */ diff --git a/src/USER-CGDNA/pair_oxdna_excv.h b/src/USER-CGDNA/pair_oxdna_excv.h index 0308c1f48..ec9ddee3e 100644 --- a/src/USER-CGDNA/pair_oxdna_excv.h +++ b/src/USER-CGDNA/pair_oxdna_excv.h @@ -1,79 +1,79 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(oxdna/excv,PairOxdnaExcv) #else #ifndef LMP_PAIR_OXDNA_EXCV_H #define LMP_PAIR_OXDNA_EXCV_H #include "pair.h" namespace LAMMPS_NS { class PairOxdnaExcv : public Pair { public: PairOxdnaExcv(class LAMMPS *); virtual ~PairOxdnaExcv(); virtual void compute_interaction_sites(double *, double *, double *, double *); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); void init_list(int, class NeighList *); double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); void write_restart_settings(FILE *); void read_restart_settings(FILE *); void write_data(FILE *); void write_data_all(FILE *); void *extract(const char *, int &); protected: // s=sugar-phosphate backbone site, b=base site, st=stacking site // excluded volume interaction double **epsilon_ss, **sigma_ss, **cut_ss_ast, **cutsq_ss_ast; double **lj1_ss, **lj2_ss, **b_ss, **cut_ss_c, **cutsq_ss_c; double **epsilon_sb, **sigma_sb, **cut_sb_ast, **cutsq_sb_ast; double **lj1_sb, **lj2_sb, **b_sb, **cut_sb_c, **cutsq_sb_c; double **epsilon_bb, **sigma_bb, **cut_bb_ast, **cutsq_bb_ast; double **lj1_bb, **lj2_bb, **b_bb, **cut_bb_c, **cutsq_bb_c; virtual void allocate(); }; } #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. */ diff --git a/src/USER-CGDNA/pair_oxdna_hbond.h b/src/USER-CGDNA/pair_oxdna_hbond.h index 409241710..1c9f37bf5 100644 --- a/src/USER-CGDNA/pair_oxdna_hbond.h +++ b/src/USER-CGDNA/pair_oxdna_hbond.h @@ -1,90 +1,90 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(oxdna/hbond,PairOxdnaHbond) PairStyle(oxdna2/hbond,PairOxdnaHbond) #else #ifndef LMP_PAIR_OXDNA_HBOND_H #define LMP_PAIR_OXDNA_HBOND_H #include "pair.h" namespace LAMMPS_NS { class PairOxdnaHbond : public Pair { public: PairOxdnaHbond(class LAMMPS *); virtual ~PairOxdnaHbond(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); void init_list(int, class NeighList *); double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); void write_restart_settings(FILE *); void read_restart_settings(FILE *); void write_data(FILE *); void write_data_all(FILE *); void *extract(const char *, int &); protected: // h-bonding interaction double **epsilon_hb, **a_hb, **cut_hb_0, **cut_hb_c, **cut_hb_lo, **cut_hb_hi; double **cut_hb_lc, **cut_hb_hc, **b_hb_lo, **b_hb_hi, **shift_hb; double **cutsq_hb_hc; double **a_hb1, **theta_hb1_0, **dtheta_hb1_ast; double **b_hb1, **dtheta_hb1_c; double **a_hb2, **theta_hb2_0, **dtheta_hb2_ast; double **b_hb2, **dtheta_hb2_c; double **a_hb3, **theta_hb3_0, **dtheta_hb3_ast; double **b_hb3, **dtheta_hb3_c; double **a_hb4, **theta_hb4_0, **dtheta_hb4_ast; double **b_hb4, **dtheta_hb4_c; double **a_hb7, **theta_hb7_0, **dtheta_hb7_ast; double **b_hb7, **dtheta_hb7_c; double **a_hb8, **theta_hb8_0, **dtheta_hb8_ast; double **b_hb8, **dtheta_hb8_c; virtual void allocate(); }; } #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. */ diff --git a/src/USER-CGDNA/pair_oxdna_stk.h b/src/USER-CGDNA/pair_oxdna_stk.h index fd0c27d38..950c27622 100644 --- a/src/USER-CGDNA/pair_oxdna_stk.h +++ b/src/USER-CGDNA/pair_oxdna_stk.h @@ -1,81 +1,81 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(oxdna/stk,PairOxdnaStk) #else #ifndef LMP_PAIR_OXDNA_STK_H #define LMP_PAIR_OXDNA_STK_H #include "pair.h" namespace LAMMPS_NS { class PairOxdnaStk : public Pair { public: PairOxdnaStk(class LAMMPS *); virtual ~PairOxdnaStk(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); void init_list(int, class NeighList *); double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); void write_restart_settings(FILE *); void read_restart_settings(FILE *); void write_data(FILE *); void write_data_all(FILE *); void *extract(const char *, int &); protected: // stacking interaction virtual double stacking_strength(double); double **epsilon_st, **a_st, **cut_st_0, **cut_st_c; double **cut_st_lo, **cut_st_hi; double **cut_st_lc, **cut_st_hc, **b_st_lo, **b_st_hi, **shift_st; double **cutsq_st_hc; double **a_st4, **theta_st4_0, **dtheta_st4_ast; double **b_st4, **dtheta_st4_c; double **a_st5, **theta_st5_0, **dtheta_st5_ast; double **b_st5, **dtheta_st5_c; double **a_st6, **theta_st6_0, **dtheta_st6_ast; double **b_st6, **dtheta_st6_c; double **a_st1, **cosphi_st1_ast, **b_st1, **cosphi_st1_c; double **a_st2, **cosphi_st2_ast, **b_st2, **cosphi_st2_c; virtual void allocate(); }; } #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. */ diff --git a/src/USER-CGDNA/pair_oxdna_xstk.h b/src/USER-CGDNA/pair_oxdna_xstk.h index c71962ab5..5c443a4da 100644 --- a/src/USER-CGDNA/pair_oxdna_xstk.h +++ b/src/USER-CGDNA/pair_oxdna_xstk.h @@ -1,90 +1,90 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(oxdna/xstk,PairOxdnaXstk) PairStyle(oxdna2/xstk,PairOxdnaXstk) #else #ifndef LMP_PAIR_OXDNA_XSTK_H #define LMP_PAIR_OXDNA_XSTK_H #include "pair.h" namespace LAMMPS_NS { class PairOxdnaXstk : public Pair { public: PairOxdnaXstk(class LAMMPS *); virtual ~PairOxdnaXstk(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); void init_list(int, class NeighList *); double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); void write_restart_settings(FILE *); void read_restart_settings(FILE *); void write_data(FILE *); void write_data_all(FILE *); void *extract(const char *, int &); protected: // cross-stacking interaction double **k_xst, **cut_xst_0, **cut_xst_c, **cut_xst_lo, **cut_xst_hi; double **cut_xst_lc, **cut_xst_hc, **b_xst_lo, **b_xst_hi; double **cutsq_xst_hc; double **a_xst1, **theta_xst1_0, **dtheta_xst1_ast; double **b_xst1, **dtheta_xst1_c; double **a_xst2, **theta_xst2_0, **dtheta_xst2_ast; double **b_xst2, **dtheta_xst2_c; double **a_xst3, **theta_xst3_0, **dtheta_xst3_ast; double **b_xst3, **dtheta_xst3_c; double **a_xst4, **theta_xst4_0, **dtheta_xst4_ast; double **b_xst4, **dtheta_xst4_c; double **a_xst7, **theta_xst7_0, **dtheta_xst7_ast; double **b_xst7, **dtheta_xst7_c; double **a_xst8, **theta_xst8_0, **dtheta_xst8_ast; double **b_xst8, **dtheta_xst8_c; virtual void allocate(); }; } #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. */ diff --git a/src/USER-DIFFRACTION/compute_saed.h b/src/USER-DIFFRACTION/compute_saed.h index 89e57f509..87785c493 100644 --- a/src/USER-DIFFRACTION/compute_saed.h +++ b/src/USER-DIFFRACTION/compute_saed.h @@ -1,63 +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 COMPUTE_CLASS ComputeStyle(saed,ComputeSAED) #else #ifndef LMP_COMPUTE_SAED_H #define LMP_COMPUTE_SAED_H #include "compute.h" namespace LAMMPS_NS { class ComputeSAED : public Compute { public: ComputeSAED(class LAMMPS *, int, char **); ~ComputeSAED(); void init(); void compute_vector(); double memory_usage(); //testing double saed_var[10]; private: int me; int *ztype; // Atomic number of the different atom types double c[3]; // Parameters controlling resolution of reciprocal space explored double dR_Ewald; // Thickness of Ewald sphere slice double prd_inv[3]; // Inverse spacing of unit cell bool echo; // echo compute_array progress bool manual; // Turn on manual recpiprocal map int nRows; // Number of relp explored double Zone[3]; // Zone axis to view SAED double R_Ewald; // Radius of Ewald sphere (distance units) double lambda; // Radiation wavelenght (distance units) double dK[3]; // spacing of reciprocal points in each dimension int Knmax[3]; // maximum integer value for K points in each dimension double Kmax; // Maximum reciprocal distance to explore int ntypes; int nlocalgroup; int *store_tmp; }; } #endif #endif diff --git a/src/USER-DIFFRACTION/compute_saed_consts.h b/src/USER-DIFFRACTION/compute_saed_consts.h index 0cce0abfc..0c07ae13a 100644 --- a/src/USER-DIFFRACTION/compute_saed_consts.h +++ b/src/USER-DIFFRACTION/compute_saed_consts.h @@ -1,458 +1,458 @@ -/* ---------------------------------------------------------------------- +/* -*- 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_COMPUTE_SAED_CONSTS_H #define LMP_COMPUTE_SAED_CONSTS_H /* The paramaters for analytical approximation of the atomic scattering factors used for electron diffraction are gathered from the resources: Colliex C et al 2004 Electron diffraction International Tables for Crystallography Volume C: Mathematical, Physical, and Chemical Tables ed E Prince (Norwell, MA: Kluwer) pp 259429 Peng L-M, Ren G, Dudarev S L and Whelan MJ 1996 Robust parameterization of elastic and absorptive electron atomic scattering factors Acta Crystallogr.A 52 25776 */ #define SAEDmaxType 98 // list of element types associated with atomic scattering factor constants static const char *SAEDtypeList[SAEDmaxType] = { "H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf"}; // list of atomic scattering factor constants for electron diffraction static const double ASFSAED[SAEDmaxType][20] = { /* Each set of four rows in this file represents a single row in the matrix First two rows are constants for 0 < sin(theta)/lambda < 2 Z-number A1 A2 A3 A4 A5 B1 B2 B3 B4 B5 Second two rows are constants for 2 < sin(theta)/lambda < 6 A1 A2 A3 A4 A5 B1 B2 B3 B4 B5*/ /* 1*/ { 0.0349, 0.1201, 0.1970, 0.0573, 0.1195, 0.5347, 3.5867, 12.3471, 18.9525, 38.6269, 0.0088, 0.0449, 0.1481, 0.2356, 0.0914, 0.1152, 1.0867, 4.9755, 16.5591, 43.2743}, /* 2*/ { 0.0317, 0.0838, 0.1526, 0.1334, 0.0164, 0.2507, 1.4751, 4.4938, 12.6646, 31.1653, 0.0084, 0.0443, 0.1314, 0.1671, 0.0666, 0.0596, 0.5360, 2.4274, 7.7852, 20.3126}, /* 3*/ { 0.0750, 0.2249, 0.5548, 1.4954, 0.9354, 0.3864, 2.9383, 15.3829, 53.5545, 138.7337, 0.0478, 0.2048, 0.5253, 1.5225, 0.9853, 0.2258, 2.1032, 12.9349, 50.7501, 136.6280}, /* 4*/ { 0.0780, 0.2210, 0.6740, 1.3867, 0.6925, 0.3131, 2.2381, 10.1517, 30.9061, 78.3273, 0.0423, 0.1874, 0.6019, 1.4311, 0.7891, 0.1445, 1.4180, 8.1165, 27.9705, 74.8684}, /* 5*/ { 0.0909, 0.2551, 0.7738, 1.2136, 0.4606, 0.2995, 2.1155, 8.3816, 24.1292, 63.1314, 0.0436, 0.1898, 0.6788, 1.3273, 0.5544, 0.1207, 1.1595, 6.2474, 21.0460, 59.3619}, /* 6*/ { 0.0893, 0.2563, 0.7570, 1.0487, 0.3575, 0.2465, 1.7100, 6.4094, 18.6113, 50.2523, 0.0489, 0.2091, 0.7537, 1.1420, 0.3555, 0.1140, 1.0825, 5.4281, 17.8811, 51.1341}, /* 7*/ { 0.1022, 0.3219, 0.7982, 0.8197, 0.1715, 0.2451, 1.7481, 6.1925, 17.3894, 48.1431, 0.0267, 0.1328, 0.5301, 1.1020, 0.4215, 0.0541, 0.5165, 2.8207, 10.6297, 34.3764}, /* 8*/ { 0.0974, 0.2921, 0.6910, 0.6990, 0.2039, 0.2067, 1.3815, 4.6943, 12.7105, 32.4726, 0.0365, 0.1729, 0.5805, 0.8814, 0.3121, 0.0652, 0.6184, 2.9449, 9.6298, 28.2194}, /* 9*/ { 0.1083, 0.3175, 0.6487, 0.5846, 0.1421, 0.2057, 1.3439, 4.2788, 11.3932, 28.7881, 0.0382, 0.1822, 0.5972, 0.7707, 0.2130, 0.0613, 0.5753, 2.6858, 8.8214, 25.6668}, /* 10*/ { 0.1269, 0.3535, 0.5582, 0.4674, 0.1460, 0.2200, 1.3779, 4.0203, 9.4934, 23.1278, 0.0380, 0.1785, 0.5494, 0.6942, 0.1918, 0.0554, 0.5087, 2.2639, 7.3316, 21.6912}, /* 11*/ { 0.2142, 0.6853, 0.7692, 1.6589, 1.4482, 0.3334, 2.3446, 10.0830, 48.3037, 138.2700, 0.1260, 0.6442, 0.8893, 1.8197, 1.2988, 0.1684, 1.7150, 8.8386, 50.8265, 147.2073}, /* 12*/ { 0.2314, 0.6866, 0.9677, 2.1882, 1.1339, 0.3278, 2.2720, 10.9241, 39.2898, 101.9748, 0.1130, 0.5575, 0.9046, 2.1580, 1.4735, 0.1356, 1.3579, 6.9255, 32.3165, 92.1138}, /* 13*/ { 0.2390, 0.6573, 1.2011, 2.5586, 1.2312, 0.3138, 2.1063, 10.4163, 34.4552, 98.5344, 0.1165, 0.5504, 1.0179, 2.6295, 1.5711, 0.1295, 1.2619, 6.8242, 28.4577, 88.4750}, /* 14*/ { 0.2519, 0.6372, 1.3795, 2.5082, 1.0500, 0.3075, 2.0174, 9.6746, 29.3744, 80.4732, 0.0567, 0.3365, 0.8104, 2.4960, 2.1186, 0.0582, 0.6155, 3.2522, 16.7929, 57.6767}, /* 15*/ { 0.2548, 0.6106, 1.4541, 2.3204, 0.8477, 0.2908, 1.8740, 8.5176, 24.3434, 63.2996, 0.1005, 0.4615, 1.0663, 2.5854, 1.2725, 0.0977, 0.9084, 4.9654, 18.5471, 54.3648}, /* 16*/ { 0.2497, 0.5628, 1.3899, 2.1865, 0.7715, 0.2681, 1.6711, 7.0267, 19.5377, 50.3888, 0.0915, 0.4312, 1.0847, 2.4671, 1.0852, 0.0838, 0.7788, 4.3462, 15.5846, 44.6365}, /* 17*/ { 0.2443, 0.5397, 1.3919, 2.0197, 0.6621, 0.2468, 1.5242, 6.1537, 16.6687, 42.3086, 0.0799, 0.3891, 1.0037, 2.3332, 1.0507, 0.0694, 0.6443, 3.5351, 12.5058, 35.8633}, /* 18*/ { 0.2385, 0.5017, 1.3428, 1.8899, 0.6079, 0.2289, 1.3694, 5.2561, 14.0928, 35.5361, 0.1044, 0.4551, 1.4232, 2.1533, 0.4459, 0.0853, 0.7701, 4.4684, 14.5864, 41.2474}, /* 19*/ { 0.4115, 1.4031, 2.2784, 2.6742, 2.2162, 0.3703, 3.3874, 13.1029, 68.9592, 194.4329, 0.2149, 0.8703, 2.4999, 2.3591, 3.0318, 0.1660, 1.6906, 8.7447, 46.7825, 165.6923}, /* 20*/ { 0.4054, 1.3880, 2.1602, 3.7532, 2.2063, 0.3499, 3.0991, 11.9608, 53.9353, 142.3892, 0.2355, 0.9916, 2.3959, 3.7252, 2.5647, 0.1742, 1.8329, 8.8407, 47.4583, 134.9613}, /* 21*/ { 0.3787, 1.2181, 2.0594, 3.2618, 2.3870, 0.3133, 2.5856, 9.5813, 41.7688, 116.7282, 0.4636, 2.0802, 2.9003, 1.4193, 2.4323, 0.3682, 4.0312, 22.6493, 71.8200, 103.3691}, /* 22*/ { 0.3825, 1.2598, 2.0008, 3.0617, 2.0694, 0.3040, 2.4863, 9.2783, 39.0751, 109.4583, 0.2123, 0.8960, 2.1765, 3.0436, 2.4439, 0.1399, 1.4568, 6.7534, 33.1168, 101.8238}, /* 23*/ { 0.3876, 1.2750, 1.9109, 2.8314, 1.8979, 0.2967, 2.3780, 8.7981, 35.9528, 101.7201, 0.2369, 1.0774, 2.1894, 3.0825, 1.7190, 0.1505, 1.6392, 7.5691, 36.8741, 107.8517}, /* 24*/ { 0.4046, 1.3696, 1.8941, 2.0800, 1.2196, 0.2986, 2.3958, 9.1406, 37.4701, 113.7121, 0.1970, 0.8228, 2.0200, 2.1717, 1.7516, 0.1197, 1.1985, 5.4097, 25.2361, 94.4290}, /* 25*/ { 0.3796, 1.2094, 1.7815, 2.5420, 1.5937, 0.2699, 2.0455, 7.4726, 31.0604, 91.5622, 0.1943, 0.8190, 1.9296, 2.4968, 2.0625, 0.1135, 1.1313, 5.0341, 24.1798, 80.5598}, /* 26*/ { 0.3946, 1.2725, 1.7031, 2.3140, 1.4795, 0.2717, 2.0443, 7.6007, 29.9714, 86.2265, 0.1929, 0.8239, 1.8689, 2.3694, 1.9060, 0.1087, 1.0806, 4.7637, 22.8500, 76.7309}, /* 27*/ { 0.4118, 1.3161, 1.6493, 2.1930, 1.2830, 0.2742, 2.0372, 7.7205, 29.9680, 84.9383, 0.2186, 0.9861, 1.8540, 2.3258, 1.4685, 0.1182, 1.2300, 5.4177, 25.7602, 80.8542}, /* 28*/ { 0.3860, 1.1765, 1.5451, 2.0730, 1.3814, 0.2478, 1.7660, 6.3107, 25.2204, 74.3146, 0.2313, 1.0657, 1.8229, 2.2609, 1.1883, 0.1210, 1.2691, 5.6870, 27.0917, 83.0285}, /* 29*/ { 0.4314, 1.3208, 1.5236, 1.4671, 0.8562, 0.2694, 1.9223, 7.3474, 28.9892, 90.6246, 0.3501, 1.6558, 1.9582, 0.2134, 1.4109, 0.1867, 1.9917, 11.3396, 53.2619, 63.2520}, /* 30*/ { 0.4288, 1.2646, 1.4472, 1.8294, 1.0934, 0.2593, 1.7998, 6.7500, 25.5860, 73.5284, 0.1780, 0.8096, 1.6744, 1.9499, 1.4495, 0.0876, 0.8650, 3.8612, 18.8726, 64.7016}, /* 31*/ { 0.4818, 1.4032, 1.6561, 2.4605, 1.1054, 0.2825, 1.9785, 8.7546, 32.5238, 98.5523, 0.2135, 0.9768, 1.6669, 2.5662, 1.6790, 0.1020, 1.0219, 4.6275, 22.8742, 80.1535}, /* 32*/ { 0.4655, 1.3014, 1.6088, 2.6998, 1.3003, 0.2647, 1.7926, 7.6071, 26.5541, 77.5238, 0.2135, 0.9761, 1.6555, 2.8938, 1.6356, 0.0989, 0.9845, 4.5527, 21.5563, 70.3903}, /* 33*/ { 0.4517, 1.2229, 1.5852, 2.7958, 1.2638, 0.2493, 1.6436, 6.8154, 22.3681, 62.0390, 0.2059, 0.9518, 1.6372, 3.0490, 1.4756, 0.0926, 0.9182, 4.3291, 19.2996, 58.9329}, /* 34*/ { 0.4477, 1.1678, 1.5843, 2.8087, 1.1956, 0.2405, 1.5442, 6.3231, 19.4610, 52.0233, 0.1574, 0.7614, 1.4834, 3.0016, 1.7978, 0.0686, 0.6808, 3.1163, 14.3458, 44.0455}, /* 35*/ { 0.4798, 1.1948, 1.8695, 2.6953, 0.8203, 0.2504, 1.5963, 6.9653, 19.8492, 50.3233, 0.1899, 0.8983, 1.6358, 3.1845, 1.1518, 0.0810, 0.7957, 3.9054, 15.7701, 45.6124}, /* 36*/ { 0.4546, 1.0993, 1.7696, 2.7068, 0.8672, 0.2309, 1.4279, 5.9449, 16.6752, 42.2243, 0.1742, 0.8447, 1.5944, 3.1507, 1.1338, 0.0723, 0.7123, 3.5192, 13.7724, 39.1148}, /* 37*/ { 1.0160, 2.8528, 3.5466, -7.7804, 12.1148, 0.4853, 5.0925, 25.7851, 130.4510, 138.6775, 0.3781, 1.4904, 3.5753, 3.0031, 3.3272, 0.1557, 1.5347, 9.9947, 51.4251, 185.9828}, /* 38*/ { 0.6703, 1.4926, 3.3368, 4.4600, 3.1501, 0.3190, 2.2287, 10.3504, 52.3291, 151.2216, 0.3723, 1.4598, 3.5124, 4.4612, 3.3031, 0.1480, 1.4643, 9.2320, 49.8807, 148.0937}, /* 39*/ { 0.6894, 1.5474, 3.2450, 4.2126, 2.9764, 0.3189, 2.2904, 10.0062, 44.0771, 125.0120, 0.3234, 1.2737, 3.2115, 4.0563, 3.7962, 0.1244, 1.1948, 7.2756, 34.1430, 111.2079}, /* 40*/ { 0.6719, 1.4684, 3.1668, 3.9557, 2.8920, 0.3036, 2.1249, 8.9236, 36.8458, 108.2049, 0.2997, 1.1879, 3.1075, 3.9740, 3.5769, 0.1121, 1.0638, 6.3891, 28.7081, 97.4289}, /* 41*/ { 0.6123, 1.2677, 3.0348, 3.3841, 2.3683, 0.2709, 1.7683, 7.2489, 27.9465, 98.5624, 0.1680, 0.9370, 2.7300, 3.8150, 3.0053, 0.0597, 0.6524, 4.4317, 19.5540, 85.5011}, /* 42*/ { 0.6773, 1.4798, 3.1788, 3.0824, 1.8384, 0.2920, 2.0606, 8.1129, 30.5336, 100.0658, 0.3069, 1.1714, 3.2293, 3.4254, 2.1224, 0.1101, 1.0222, 5.9613, 25.1965, 93.5831}, /* 43*/ { 0.7082, 1.6392, 3.1993, 3.4327, 1.8711, 0.2976, 2.2106, 8.5246, 33.1456, 96.6377, 0.2928, 1.1267, 3.1675, 3.6619, 2.5942, 0.1020, 0.9481, 5.4713, 23.8153, 82.8991}, /* 44*/ { 0.6735, 1.4934, 3.0966, 2.7254, 1.5597, 0.2773, 1.9716, 7.3249, 26.6891, 90.5581, 0.2604, 1.0442, 3.0761, 3.2175, 1.9448, 0.0887, 0.8240, 4.8278, 19.8977, 80.4566}, /* 45*/ { 0.6413, 1.3690, 2.9854, 2.6952, 1.5433, 0.2580, 1.7721, 6.3854, 23.2549, 85.1517, 0.2713, 1.0556, 3.1416, 3.0451, 1.7179, 0.0907, 0.8324, 4.7702, 19.7862, 80.2540}, /* 46*/ { 0.5904, 1.1775, 2.6519, 2.2875, 0.8689, 0.2324, 1.5019, 5.1591, 15.5428, 46.8213, 0.2003, 0.8779, 2.6135, 2.8594, 1.0258, 0.0659, 0.6111, 3.5563, 12.7638, 44.4283}, /* 47*/ { 0.6377, 1.3790, 2.8294, 2.3631, 1.4553, 0.2466, 1.6974, 5.7656, 20.0943, 76.7372, 0.2739, 1.0503, 3.1564, 2.7543, 1.4328, 0.0881, 0.8028, 4.4451, 18.7011, 79.2633}, /* 48*/ { 0.6364, 1.4247, 2.7802, 2.5973, 1.7886, 0.2407, 1.6823, 5.6588, 20.7219, 69.1109, 0.3072, 1.1303, 3.2046, 2.9329, 1.6560, 0.0966, 0.8856, 4.6273, 20.6789, 73.4723}, /* 49*/ { 0.6768, 1.6589, 2.7740, 3.1835, 2.1326, 0.2522, 1.8545, 6.2936, 25.1457, 84.5448, 0.3564, 1.3011, 3.2424, 3.4839, 2.0459, 0.1091, 1.0452, 5.0900, 24.6578, 88.0513}, /* 50*/ { 0.7224, 1.9610, 2.7161, 3.5603, 1.8972, 0.2651, 2.0604, 7.3011, 27.5493, 81.3349, 0.2966, 1.1157, 3.0973, 3.8156, 2.5281, 0.0896, 0.8268, 4.2242, 20.6900, 71.3399}, /* 51*/ { 0.7106, 1.9247, 2.6149, 3.8322, 1.8899, 0.2562, 1.9646, 6.8852, 24.7648, 68.9168, 0.2725, 1.0651, 2.9940, 4.0697, 2.5682, 0.0809, 0.7488, 3.8710, 18.8800, 60.6499}, /* 52*/ { 0.6947, 1.8690, 2.5356, 4.0013, 1.8955, 0.2459, 1.8542, 6.4411, 22.1730, 59.2206, 0.2422, 0.9692, 2.8114, 4.1509, 2.8161, 0.0708, 0.6472, 3.3609, 16.0752, 50.1724}, /* 53*/ { 0.7047, 1.9484, 2.5940, 4.1526, 1.5057, 0.2455, 1.8638, 6.7639, 21.8007, 56.4395, 0.2617, 1.0325, 2.8097, 4.4809, 2.3190, 0.0749, 0.6914, 3.4634, 16.3603, 48.2522}, /* 54*/ { 0.6737, 1.7908, 2.4129, 4.2100, 1.7058, 0.2305, 1.6890, 5.8218, 18.3928, 47.2496, 0.2334, 0.9496, 2.6381, 4.4680, 2.5020, 0.0655, 0.6050, 3.0389, 14.0809, 41.0005}, /* 55*/ { 1.2704, 3.8018, 5.6618, 0.9205, 4.8105, 0.4356, 4.2058, 23.4342, 136.7780, 171.7561, 0.5713, 2.4866, 4.9795, 4.0198, 4.4403, 0.1626, 1.8213, 11.1049, 49.0568, 202.9987}, /* 56*/ { 0.9049, 2.6076, 4.8498, 5.1603, 4.7388, 0.3066, 2.4363, 12.1821, 54.6135, 161.9978, 0.5229, 2.2874, 4.7243, 5.0807, 5.6389, 0.1434, 1.6019, 9.4511, 42.7685, 148.4969}, /* 57*/ { 0.8405, 2.3863, 4.6139, 5.1514, 4.7949, 0.2791, 2.1410, 10.3400, 41.9148, 132.0204, 0.5461, 2.3856, 5.0653, 5.7601, 4.0463, 0.1479, 1.6552, 10.0059, 47.3245, 145.8464}, /* 58*/ { 0.8551, 2.3915, 4.5772, 5.0278, 4.5118, 0.2805, 2.1200, 10.1808, 42.0633, 130.9893, 0.2227, 1.0760, 2.9482, 5.8496, 7.1834, 0.0571, 0.5946, 3.2022, 16.4253, 95.7030}, /* 59*/ { 0.9096, 2.5313, 4.5266, 4.6376, 4.3690, 0.2939, 2.2471, 10.8266, 48.8842, 147.6020, 0.5237, 2.2913, 4.6161, 4.7233, 4.8173, 0.1360, 1.5068, 8.8213, 41.9536, 141.2424}, /* 60*/ { 0.8807, 2.4183, 4.4448, 4.6858, 4.1725, 0.2802, 2.0836, 10.0357, 47.4506, 146.9976, 0.5368, 2.3301, 4.6058, 4.6621, 4.4622, 0.1378, 1.5140, 8.8719, 43.5967, 141.8065}, /* 61*/ { 0.9471, 2.5463, 4.3523, 4.4789, 3.9080, 0.2977, 2.2276, 10.5762, 49.3619, 145.3580, 0.5232, 2.2627, 4.4552, 4.4787, 4.5073, 0.1317, 1.4336, 8.3087, 40.6010, 135.9196}, /* 62*/ { 0.9699, 2.5837, 4.2778, 4.4575, 3.5985, 0.3003, 2.2447, 10.6487, 50.7994, 146.4179, 0.5162, 2.2302, 4.3449, 4.3598, 4.4292, 0.1279, 1.3811, 7.9629, 39.1213, 132.7846}, /* 63*/ { 0.8694, 2.2413, 3.9196, 3.9694, 4.5498, 0.2653, 1.8590, 8.3998, 36.7397, 125.7089, 0.5272, 2.2844, 4.3361, 4.3178, 4.0908, 0.1285, 1.3943, 8.1081, 40.9631, 134.1233}, /* 64*/ { 0.9673, 2.4702, 4.1148, 4.4972, 3.2099, 0.2909, 2.1014, 9.7067, 43.4270, 125.9474, 0.9664, 3.4052, 5.0803, 1.4991, 4.2528, 0.2641, 2.6586, 16.2213, 80.2060, 92.5359}, /* 65*/ { 0.9325, 2.3673, 3.8791, 3.9674, 3.7996, 0.2761, 1.9511, 8.9296, 41.5937, 131.0122, 0.5110, 2.1570, 4.0308, 3.9936, 4.2466, 0.1210, 1.2704, 7.1368, 35.0354, 123.5062}, /* 66*/ { 0.9505, 2.3705, 3.8218, 4.0471, 3.4451, 0.2773, 1.9469, 8.8862, 43.0938, 133.1396, 0.4974, 2.1097, 3.8906, 3.8100, 4.3084, 0.1157, 1.2108, 6.7377, 32.4150, 116.9225}, /* 67*/ { 0.9248, 2.2428, 3.6182, 3.7910, 3.7912, 0.2660, 1.8183, 7.9655, 33.1129, 101.8139, 0.4679, 1.9693, 3.7191, 3.9632, 4.2432, 0.1069, 1.0994, 5.9769, 27.1491, 96.3119}, /* 68*/ { 1.0373, 2.4824, 3.6558, 3.8925, 3.0056, 0.2944, 2.0797, 9.4156, 45.8056, 132.7720, 0.5034, 2.1088, 3.8232, 3.7299, 3.8963, 0.1141, 1.1769, 6.6087, 33.4332, 116.4913}, /* 69*/ { 1.0075, 2.3787, 3.5440, 3.6932, 3.1759, 0.2816, 1.9486, 8.7162, 41.8420, 125.0320, 0.4839, 2.0262, 3.6851, 3.5874, 4.0037, 0.1081, 1.1012, 6.1114, 30.3728, 110.5988}, /* 70*/ { 1.0347, 2.3911, 3.4619, 3.6556, 3.0052, 0.2855, 1.9679, 8.7619, 42.3304, 125.6499, 0.5221, 2.1695, 3.7567, 3.6685, 3.4274, 0.1148, 1.1860, 6.7520, 35.6807, 118.0692}, /* 71*/ { 0.9927, 2.2436, 3.3554, 3.7813, 3.0994, 0.2701, 1.8073, 7.8112, 34.4849, 103.3526, 0.4680, 1.9466, 3.5428, 3.8490, 3.6594, 0.1015, 1.0195, 5.6058, 27.4899, 95.2846}, /* 72*/ { 1.0295, 2.2911, 3.4110, 3.9497, 2.4925, 0.2761, 1.8625, 8.0961, 34.2712, 98.5295, 0.4048, 1.7370, 3.3399, 3.9448, 3.7293, 0.0868, 0.8585, 4.6378, 21.6900, 80.2408}, /* 73*/ { 1.0190, 2.2291, 3.4097, 3.9252, 2.2679, 0.2694, 1.7962, 7.6944, 31.0942, 91.1089, 0.3835, 1.6747, 3.2986, 4.0462, 3.4303, 0.0810, 0.8020, 4.3545, 19.9644, 73.6337}, /* 74*/ { 0.9853, 2.1167, 3.3570, 3.7981, 2.2798, 0.2569, 1.6745, 7.0098, 26.9234, 81.3910, 0.3661, 1.6191, 3.2455, 4.0856, 3.2064, 0.0761, 0.7543, 4.0952, 18.2886, 68.0967}, /* 75*/ { 0.9914, 2.0858, 3.4531, 3.8812, 1.8526, 0.2548, 1.6518, 6.8845, 26.7234, 81.7215, 0.3933, 1.6973, 3.4202, 4.1274, 2.6158, 0.0806, 0.7972, 4.4237, 19.5692, 68.7477}, /* 76*/ { 0.9813, 2.0322, 3.3665, 3.6235, 1.9741, 0.2487, 1.5973, 6.4737, 23.2817, 70.9254, 0.3854, 1.6555, 3.4129, 4.1111, 2.4106, 0.0787, 0.7638, 4.2441, 18.3700, 65.1071}, /* 77*/ { 1.0194, 2.0645, 3.4425, 3.4914, 1.6976, 0.2554, 1.6475, 6.5966, 23.2269, 70.0272, 0.3510, 1.5620, 3.2946, 4.0615, 2.4382, 0.0706, 0.6904, 3.8266, 16.0812, 58.7638}, /* 78*/ { 0.9148, 1.8096, 3.2134, 3.2953, 1.5754, 0.2263, 1.3813, 5.3243, 17.5987, 60.0171, 0.3083, 1.4158, 2.9662, 3.9349, 2.1709, 0.0609, 0.5993, 3.1921, 12.5285, 49.7675}, /* 79*/ { 0.9674, 1.8916, 3.3993, 3.0524, 1.2607, 0.2358, 1.4712, 5.6758, 18.7119, 61.5286, 0.3055, 1.3945, 2.9617, 3.8990, 2.0026, 0.0596, 0.5827, 3.1035, 11.9693, 47.9106}, /* 80*/ { 1.0033, 1.9469, 3.4396, 3.1548, 1.4180, 0.2413, 1.5298, 5.8009, 19.4520, 60.5753, 0.3593, 1.5736, 3.5237, 3.8109, 1.6953, 0.0694, 0.6758, 3.8457, 15.6203, 56.6614}, /* 81*/ { 1.0689, 2.1038, 3.6039, 3.4927, 1.8283, 0.2540, 1.6715, 6.3509, 23.1531, 78.7099, 0.3511, 1.5489, 3.5676, 4.0900, 2.5251, 0.0672, 0.6522, 3.7420, 15.9791, 65.1354}, /* 82*/ { 1.0891, 2.1867, 3.6160, 3.8031, 1.8994, 0.2552, 1.7174, 6.5131, 23.9170, 74.7039, 0.3540, 1.5453, 3.5975, 4.3152, 2.7743, 0.0668, 0.6465, 3.6968, 16.2056, 61.4909}, /* 83*/ { 1.1007, 2.2306, 3.5689, 4.1549, 2.0382, 0.2546, 1.7351, 6.4948, 23.6464, 70.3780, 0.3530, 1.5258, 3.5815, 4.5532, 3.0714, 0.0661, 0.6324, 3.5906, 15.9962, 57.5760}, /* 84*/ { 1.1568, 2.4353, 3.6459, 4.4064, 1.7179, 0.2648, 1.8786, 7.1749, 25.1766, 69.2821, 0.3673, 1.5772, 3.7079, 4.8582, 2.8440, 0.0678, 0.6527, 3.7396, 17.0668, 55.9789}, /* 85*/ { 1.0909, 2.1976, 3.3831, 4.6700, 2.1277, 0.2466, 1.6707, 6.0197, 20.7657, 57.2663, 0.3547, 1.5206, 3.5621, 5.0184, 3.0075, 0.0649, 0.6188, 3.4696, 15.6090, 49.4818}, /* 86*/ { 1.0756, 2.1630, 3.3178, 4.8852, 2.0489, 0.2402, 1.6169, 5.7644, 19.4568, 52.5009, 0.4586, 1.7781, 3.9877, 5.7273, 1.5460, 0.0831, 0.7840, 4.3599, 20.0128, 62.1535}, /* 87*/ { 1.4282, 3.5081, 5.6767, 4.1964, 3.8946, 0.3183, 2.6889, 13.4816, 54.3866, 200.8321, 0.8282, 2.9941, 5.6597, 4.9292, 4.2889, 0.1515, 1.6163, 9.7752, 42.8480, 190.7366}, /* 88*/ { 1.3127, 3.1243, 5.2988, 5.3891, 5.4133, 0.2887, 2.2897, 10.8276, 43.5389, 145.6109, 1.4129, 4.4269, 7.0460, -1.0573, 8.6430, 0.2921, 3.1381, 19.6767, 102.0430, 113.9798}, /* 89*/ { 1.3128, 3.1021, 5.3385, 5.9611, 4.7562, 0.2861, 2.2509, 10.5287, 41.7796, 128.2973, 0.7169, 2.5710, 5.1791, 6.3484, 5.6474, 0.1263, 1.2900, 7.3686, 32.4490, 118.0558}, /* 90*/ { 1.2553, 2.9178, 5.0862, 6.1206, 4.7122, 0.2701, 2.0636, 9.3051, 34.5977, 107.9200, 0.6958, 2.4936, 5.1269, 6.6988, 5.0799, 0.1211, 1.2247, 6.9398, 30.0991, 105.1960}, /* 91*/ { 1.3218, 3.1444, 5.4371, 5.6444, 4.0107, 0.2827, 2.2250, 10.2454, 41.1162, 124.4449, 1.2502, 4.2284, 7.0489, 1.1390, 5.8222, 0.2415, 2.6442, 16.3313, 73.5757, 91.9401}, /* 92*/ { 1.3382, 3.2043, 5.4558, 5.4839, 3.6342, 0.2838, 2.2452, 10.2519, 41.7251, 124.9023, 0.6410, 2.2643, 4.8713, 5.9287, 5.3935, 0.1097, 1.0644, 5.7907, 25.0261, 101.3899}, /* 93*/ { 1.5193, 4.0053, 6.5327, -0.1402, 6.7489, 0.3213, 2.8206, 14.8878, 68.9103, 81.7257, 0.6938, 2.4652, 5.1227, 5.5965, 4.8543, 0.1171, 1.1757, 6.4053, 27.5217, 103.0482}, /* 94*/ { 1.3517, 3.2937, 5.3213, 4.6466, 3.5714, 0.2813, 2.2418, 9.9952, 42.7939, 132.1739, 0.6902, 2.4509, 5.1284, 5.0339, 4.8575, 0.1153, 1.1545, 6.2291, 27.0741, 111.3150}, /* 95*/ { 1.2135, 2.7962, 4.7545, 4.5731, 4.4786, 0.2483, 1.8437, 7.5421, 29.3841, 112.4579, 0.7577, 2.7264, 5.4184, 4.8198, 4.1013, 0.1257, 1.3044, 7.1035, 32.4649, 118.8647}, /* 96*/ { 1.2937, 3.1100, 5.0393, 4.7546, 3.5031, 0.2638, 2.0341, 8.7101, 35.2992, 109.4972, 0.7567, 2.7565, 5.4364, 5.1918, 3.5643, 0.1239, 1.2979, 7.0798, 32.7871, 110.1512}, /* 97*/ { 1.2915, 3.1023, 4.9309, 4.6009, 3.4661, 0.2611, 2.0023, 8.4377, 34.1559, 105.8911, 0.7492, 2.7267, 5.3521, 5.0369, 3.5321, 0.1217, 1.2651, 6.8101, 31.6088, 106.4853}, /* 98*/ { 1.2089, 2.7391, 4.3482, 4.0047, 4.6497, 0.2421, 1.7487, 6.7262, 23.2153, 80.3108, 0.8100, 3.0001, 5.4635, 4.1756, 3.5066, 0.1310, 1.4038, 7.6057, 34.0186, 90.5226}, }; #endif diff --git a/src/USER-DIFFRACTION/compute_xrd.h b/src/USER-DIFFRACTION/compute_xrd.h index 92a59fcf2..61e1dae1b 100644 --- a/src/USER-DIFFRACTION/compute_xrd.h +++ b/src/USER-DIFFRACTION/compute_xrd.h @@ -1,60 +1,60 @@ -/* ---------------------------------------------------------------------- +/* -*- 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 COMPUTE_CLASS ComputeStyle(xrd,ComputeXRD) #else #ifndef LMP_COMPUTE_XRD_H #define LMP_COMPUTE_XRD_H #include "compute.h" namespace LAMMPS_NS { class ComputeXRD : public Compute { public: ComputeXRD(class LAMMPS *, int, char **); ~ComputeXRD(); void init(); void compute_array(); double memory_usage(); private: int me; int *ztype; // Atomic number of the different atom types double Min2Theta; // Minimum 2theta value (input in 2theta rad) double Max2Theta; // Maximum 2theta value (input in 2theta rad) double Kmax; // Maximum reciprocal distance to explore double c[3]; // Resolution parameters for reciprocal space explored int Knmax[3]; // maximum integer value for K points in each dimension double dK[3]; // Parameters controlling resolution of reciprocal space explored double prd_inv[3]; // Inverse spacing of unit cell int LP; // Switch to turn on Lorentz-Polarization factor 1=on bool echo; // echo compute_array progress bool manual; // Turn on manual recpiprocal map int ntypes; int nlocalgroup; double lambda; // Radiation wavelenght (distance units) int radflag; int *store_tmp; }; } #endif #endif diff --git a/src/USER-DIFFRACTION/compute_xrd_consts.h b/src/USER-DIFFRACTION/compute_xrd_consts.h index 1ca0d6bd6..582cecae0 100644 --- a/src/USER-DIFFRACTION/compute_xrd_consts.h +++ b/src/USER-DIFFRACTION/compute_xrd_consts.h @@ -1,506 +1,506 @@ -/* ---------------------------------------------------------------------- +/* -*- 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_COMPUTE_XRD_CONSTS_H #define LMP_COMPUTE_XRD_CONSTS_H /* The paramaters for analytical approximation of the atomic scattering factors used for x-ray diffraction are gathered from the resources: Brown P J, Fox A G, Maslen E N, O’Keefe M A and Willis B T M 2004 Intensity of diffraction intensities International Tables for Crystallography Volume C: Mathematical, Physical, and Chemical Tables ed E Prince (Norwell, MA: Kluwer Academic Publishers) pp 55495 Fox A G, O’Keefe M A and Tabbernor M A 1989 Relativistic Hartree Fock x-ray and electron atomic scattering factors at high angles Acta Crystallogr. A 45 78693 */ #define XRDmaxType 210 static const char *XRDtypeList[XRDmaxType] = { "H", "He1-", "He", "Li", "Li1+", "Be", "Be2+", "B", "C", "Cval", "N", "O", "O1-", "F", "F1-", "Ne", "Na", "Na1+", "Mg", "Mg2+", "Al", "Al3+", "Si", "Sival", "Si4+", "P", "S", "Cl", "Cl1-", "Ar", "K", "Ca", "Ca2+", "Sc", "Sc3+", "Ti", "Ti2+", "Ti3+", "Ti4+", "V", "V2+", "V3+", "V5+", "Cr", "Cr2+", "Cr3+", "Mn", "Mn2+", "Mn3+", "Mn4+", "Fe", "Fe2+", "Fe3+", "Co", "Co2+", "Co", "Ni", "Ni2+", "Ni3+", "Cu", "Cu1+", "Cu2+", "Zn", "Zn2+", "Ga", "Ga3+", "Ge", "Ge4+", "As", "Se", "Br", "Br1-", "Kr", "Rb", "Rb1+", "Sr", "Sr2+", "Y", "Y3+", "Zr", "Zr4+", "Nb", "Nb3+", "Nb5+", "Mo", "Mo3+", "Mo5+", "Mo6+", "Tc", "Ru", "Ru3+", "Ru4+", "Rh", "Rh3+", "Rh4+", "Pd", "Pd2+", "Pd4+", "Ag", "Ag1+", "Ag2+", "Cd", "Cd2+", "In", "In3+", "Sn", "Sn2+", "Sn4+", "Sb", "Sb3+", "Sb5+", "Te", "I", "I1-", "Xe", "Cs", "Cs1+", "Ba", "Ba2+", "La", "La3+", "Ce", "Ce3+", "Ce4+", "Pr", "Pr3+", "Pr4+", "Nd", "Nd3+", "Pm", "Pm3+", "Sm", "Sm3+", "Eu", "Eu2+", "Eu3+", "Gd", "Gd3+", "Tb", "Tb3+", "Dy", "Dy3+", "Ho", "Ho3+", "Er", "Er3+", "Tm", "Tm3+", "Yb", "Yb2+", "Yb3+", "Lu", "Lu3+", "Hf", "Hf4+", "Ta", "Ta5+", "W", "W6+", "Re", "Os", "Os4+", "Ir", "Ir3+", "Ir4+", "Pt", "Pt2+", "Pt4+", "Au", "Au1+", "Au3+", "Hg", "Hg1+", "Hg2+", "Tl", "Tl1+", "Tl3+", "Pb", "Pb2+", "Pb4+", "Bi", "Bi3+", "Bi5+", "Po", "At", "Rn", "Fr", "Ra", "Ra2+", "Ac", "Ac3+", "Th", "Th4+", "Pa", "U", "U3+", "U4+", "U6+", "Np", "Np3+", "Np4+", "Np6+", "Pu", "Pu3+", "Pu4+", "Pu6+", "Am", "Cm", "Bk", "Cf"}; // a list of atomic scattering factor constants for x-ray diffraction static const double ASFXRD[XRDmaxType][9] = { /* Each set of two rows in this file contains the constants for 0 < sin(theta)/lambda < 2 A1, B1, A2, B2, A3, B3, A4, B4, C */ {0.489918, 20.6593, 0.262003, 7.74039, 0.196767, 49.5519, 0.049879, 2.20159, 0.001305}, {0.897661, 53.1368, 0.565616, 15.187, 0.415815, 186.576, 0.116973, 3.56709, 0.002389}, { 0.8734, 9.1037, 0.6309, 3.3568, 0.3112, 22.9276, 0.178, 0.9821, 0.0064}, { 1.1282, 3.9546, 0.7508, 1.0524, 0.6175, 85.3905, 0.4653, 68.261, 0.0377}, { 0.6968, 4.6237, 0.7888, 1.9557, 0.3414, 0.6316, 0.7029, 0.542, 0.0167}, { 1.5919, 43.6427, 1.1278, 1.8623, 0.5391, 103.483, 0.7029, 0.542, 0.0385}, { 6.2603, 0.0027, 0.8849, 0.8313, 0.7993, 2.2758, 0.1647, 5.1146, -6.1092}, { 2.0545, 23.2185, 1.3326, 1.021, 1.0979, 60.3498, 0.7068, 0.1403, -0.1932}, { 2.31, 20.8439, 1.02, 10.2075, 1.5886, 0.5687, 0.865, 51.6512, 0.2156}, { 2.26069, 22.6907, 1.56165, 0.656665, 1.05075, 9.75618, 0.839259, 55.5949, 0.286977}, { 12.2126, 0.0057, 3.1322, 9.8933, 2.0125, 28.9975, 1.1663, 0.5826, -11.529}, { 3.0485, 13.2771, 2.2868, 5.7011, 1.5463, 0.3239, 0.867, 32.9089, 0.2508}, { 4.1916, 12.8573, 1.63969, 4.17236, 1.52673, -47.0179, 20.307, -0.01404, 21.9412}, { 3.5392, 10.2825, 2.6412, 4.2944, 1.517, 0.2615, 1.0243, 26.1476, 0.2776}, { 3.6322, 5.27756, 3.51057, 14.7353, 1.26064, 0.442258, 0.940706, 47.3437, 0.653396}, { 3.9553, 8.4042, 3.1125, 3.4262, 1.4546, 0.2306, 1.1251, 21.7184, 0.3515}, { 4.7626, 3.285, 3.1736, 8.8422, 1.2674, 0.3136, 1.1128, 129.424, 0.676}, { 3.2565, 2.6671, 3.9362, 6.1153, 1.3998, 0.2001, 1.0032, 14.039, 0.404}, { 5.4204, 2.8275, 2.1735, 79.2611, 1.2269, 0.3808, 2.3073, 7.1937, 0.8584}, { 3.4988, 2.1676, 3.8378, 4.7542, 1.3284, 0.185, 0.8497, 10.1411, 0.4853}, { 6.4202, 3.0387, 1.9002, 0.7426, 1.5936, 31.5472, 1.9646, 85.0886, 1.1151}, { 4.17448, 1.93816, 3.3876, 4.14553, 1.20296, 0.228753, 0.528137, 8.28524, 0.706786}, { 6.2915, 2.4386, 3.0353, 32.3337, 1.9891, 0.6785, 1.541, 81.6937, 1.1407}, { 5.66269, 2.6652, 3.07164, 38.6634, 2.62446, 0.916946, 1.3932, 93.5458, 1.24707}, { 4.43918, 1.64167, 3.20345, 3.43757, 1.19453, 0.2149, 0.41653, 6.65365, 0.746297}, { 6.4345, 1.9067, 4.1791, 27.157, 1.78, 0.526, 1.4908, 68.1645, 1.1149}, { 6.9053, 1.4679, 5.2034, 22.2151, 1.4379, 0.2536, 1.5863, 56.172, 0.8669}, { 11.4604, 0.0104, 7.1964, 1.1662, 6.2556, 18.5194, 1.6455, 47.7784, -9.5574}, { 18.2915, 0.0066, 7.2084, 1.1717, 6.5337, 19.5424, 2.3386, 60.4486, -16.378}, { 7.4845, 0.9072, 6.7723, 14.8407, 0.6539, 43.8983, 1.6442, 33.3929, 1.4445}, { 8.2186, 12.7949, 7.4398, 0.7748, 1.0519, 213.187, 0.8659, 41.6841, 1.4228}, { 8.6266, 10.4421, 7.3873, 0.6599, 1.5899, 85.7484, 1.0211, 178.437, 1.3751}, { 15.6348, -0.0074, 7.9518, 0.6089, 8.4372, 10.3116, 0.8537, 25.9905, -14.875}, { 9.189, 9.0213, 7.3679, 0.5729, 1.6409, 136.108, 1.468, 51.3531, 1.3329}, { 13.4008, 0.29854, 8.0273, 7.9629, 1.65943, -0.28604, 1.57936, 16.0662, -6.6667}, { 9.7595, 7.8508, 7.3558, 0.5, 1.6991, 35.6338, 1.9021, 116.105, 1.2807}, { 9.11423, 7.5243, 7.62174, 0.457585, 2.2793, 19.5361, 0.087899, 61.6558, 0.897155}, { 17.7344, 0.22061, 8.73816, 7.04716, 5.25691, -0.15762, 1.92134, 15.9768, -14.652}, { 19.5114, 0.178847, 8.23473, 6.67018, 2.01341, -0.29263, 1.5208, 12.9464, -13.28}, { 10.2971, 6.8657, 7.3511, 0.4385, 2.0703, 26.8938, 2.0571, 102.478, 1.2199}, { 10.106, 6.8818, 7.3541, 0.4409, 2.2884, 20.3004, 0.0223, 115.122, 1.2298}, { 9.43141, 6.39535, 7.7419, 0.383349, 2.15343, 15.1908, 0.016865, 63.969, 0.656565}, { 15.6887, 0.679003, 8.14208, 5.40135, 2.03081, 9.97278, -9.576, 0.940464, 1.7143}, { 10.6406, 6.1038, 7.3537, 0.392, 3.324, 20.2626, 1.4922, 98.7399, 1.1832}, { 9.54034, 5.66078, 7.7509, 0.344261, 3.58274, 13.3075, 0.509107, 32.4224, 0.616898}, { 9.6809, 5.59463, 7.81136, 0.334393, 2.87603, 12.8288, 0.113575, 32.8761, 0.518275}, { 11.2819, 5.3409, 7.3573, 0.3432, 3.0193, 17.8674, 2.2441, 83.7543, 1.0896}, { 10.8061, 5.2796, 7.362, 0.3435, 3.5268, 14.343, 0.2184, 41.3235, 1.0874}, { 9.84521, 4.91797, 7.87194, 0.294393, 3.56531, 10.8171, 0.323613, 24.1281, 0.393974}, { 9.96253, 4.8485, 7.97057, 0.283303, 2.76067, 10.4852, 0.054447, 27.573, 0.251877}, { 11.7695, 4.7611, 7.3573, 0.3072, 3.5222, 15.3535, 2.3045, 76.8805, 1.0369}, { 11.0424, 4.6538, 7.374, 0.3053, 4.1346, 12.0546, 0.4399, 31.2809, 1.0097}, { 11.1764, 4.6147, 7.3863, 0.3005, 3.3948, 11.6729, 0.0724, 38.5566, 0.9707}, { 12.2841, 4.2791, 7.3409, 0.2784, 4.0034, 13.5359, 2.3488, 71.1692, 1.0118}, { 11.2296, 4.1231, 7.3883, 0.2726, 4.7393, 10.2443, 0.7108, 25.6466, 0.9324}, { 10.338, 3.90969, 7.88173, 0.238668, 4.76795, 8.35583, 0.725591, 18.3491, 0.286667}, { 12.8376, 3.8785, 7.292, 0.2565, 4.4438, 12.1763, 2.38, 66.3421, 1.0341}, { 11.4166, 3.6766, 7.4005, 0.2449, 5.3442, 8.873, 0.9773, 22.1626, 0.8614}, { 10.7806, 3.5477, 7.75868, 0.22314, 5.22746, 7.64468, 0.847114, 16.9673, 0.386044}, { 13.338, 3.5828, 7.1676, 0.247, 5.6158, 11.3966, 1.6735, 64.8126, 1.191}, { 11.9475, 3.3669, 7.3573, 0.2274, 6.2455, 8.6625, 1.5578, 25.8487, 0.89}, { 11.8168, 3.37484, 7.11181, 0.244078, 5.78135, 7.9876, 1.14523, 19.897, 1.14431}, { 14.0743, 3.2655, 7.0318, 0.2333, 5.1652, 10.3163, 2.41, 58.7097, 1.3041}, { 11.9719, 2.9946, 7.3862, 0.2031, 6.4668, 7.0826, 1.394, 18.0995, 0.7807}, { 15.2354, 3.0669, 6.7006, 0.2412, 4.3591, 10.7805, 2.9623, 61.4135, 1.7189}, { 12.692, 2.81262, 6.69883, 0.22789, 6.06692, 6.36441, 1.0066, 14.4122, 1.53545}, { 16.0816, 2.8509, 6.3747, 0.2516, 3.7068, 11.4468, 3.683, 54.7625, 2.1313}, { 12.9172, 2.53718, 6.70003, 0.205855, 6.06791, 5.47913, 0.859041, 11.603, 1.45572}, { 16.6723, 2.6345, 6.0701, 0.2647, 3.4313, 12.9479, 4.2779, 47.7972, 2.531}, { 17.0006, 2.4098, 5.8196, 0.2726, 3.9731, 15.2372, 4.3543, 43.8163, 2.8409}, { 17.1789, 2.1723, 5.2358, 16.5796, 5.6377, 0.2609, 3.9851, 41.4328, 2.9557}, { 17.1718, 2.2059, 6.3338, 19.3345, 5.5754, 0.2871, 3.7272, 58.1535, 3.1776}, { 17.3555, 1.9384, 6.7286, 16.5623, 5.5493, 0.2261, 3.5375, 39.3972, 2.825}, { 17.1784, 1.7888, 9.6435, 17.3151, 5.1399, 0.2748, 1.5292, 164.934, 3.4873}, { 17.5816, 1.7139, 7.6598, 14.7957, 5.8981, 0.1603, 2.7817, 31.2087, 2.0782}, { 17.5663, 1.5564, 9.8184, 14.0988, 5.422, 0.1664, 2.6694, 132.376, 2.5064}, { 18.0874, 1.4907, 8.1373, 12.6963, 2.5654, -24.5651, 34.193, -0.0138, 41.4025}, { 17.776, 1.4029, 10.2946, 12.8006, 5.72629, 0.125599, 3.26588, 104.354, 1.91213}, { 17.9268, 1.35417, 9.1531, 11.2145, 1.76795, -22.6599, 33.108, -0.01319, 40.2602}, { 17.8765, 1.27618, 10.948, 11.916, 5.41732, 0.117622, 3.65721, 87.6627, 2.06929}, { 18.1668, 1.2148, 10.0562, 10.1483, 1.01118, 21.6054, -2.6479, -0.10276, 9.41454}, { 17.6142, 1.18865, 12.0144, 11.766, 4.04183, 0.204785, 3.53346, 69.7957, 3.75591}, { 19.8812, 0.019175, 18.0653, 1.13305, 11.0177, 10.1621, 1.94715, 28.3389, -12.912}, { 17.9163, 1.12446, 13.3417, 0.028781, 10.799, 9.28206, 0.337905, 25.7228, -6.3934}, { 3.7025, 0.2772, 17.2356, 1.0958, 12.8876, 11.004, 3.7429, 61.6584, 4.3875}, { 21.1664, 0.014734, 18.2017, 1.03031, 11.7423, 9.53659, 2.30951, 26.6307, -14.421}, { 21.0149, 0.014345, 18.0992, 1.02238, 11.4632, 8.78809, 0.740625, 23.3452, -14.316}, { 17.8871, 1.03649, 11.175, 8.48061, 6.57891, 0.058881, 0, 0, 0.344941}, { 19.1301, 0.864132, 11.0948, 8.14487, 4.64901, 21.5707, 2.71263, 86.8472, 5.40428}, { 19.2674, 0.80852, 12.9182, 8.43467, 4.86337, 24.7997, 1.56756, 94.2928, 5.37814}, { 18.5638, 0.847329, 13.2885, 8.37164, 9.32602, 0.017662, 3.00964, 22.887, -3.1892}, { 18.5003, 0.844582, 13.1787, 8.12534, 4.71304, 0.36495, 2.18535, 20.8504, 1.42357}, { 19.2957, 0.751536, 14.3501, 8.21758, 4.73425, 25.8749, 1.28918, 98.6062, 5.328}, { 18.8785, 0.764252, 14.1259, 7.84438, 3.32515, 21.2487, -6.1989, -0.01036, 11.8678}, { 18.8545, 0.760825, 13.9806, 7.62436, 2.53464, 19.3317, -5.6526, -0.0102, 11.2835}, { 19.3319, 0.698655, 15.5017, 7.98929, 5.29537, 25.2052, 0.605844, 76.8986, 5.26593}, { 19.1701, 0.696219, 15.2096, 7.55573, 4.32234, 22.5057, 0, 0, 5.2916}, { 19.2493, 0.683839, 14.79, 7.14833, 2.89289, 17.9144, -7.9492, 0.005127, 13.0174}, { 19.2808, 0.6446, 16.6885, 7.4726, 4.8045, 24.6605, 1.0463, 99.8156, 5.179}, { 19.1812, 0.646179, 15.9719, 7.19123, 5.27475, 21.7326, 0.357534, 66.1147, 5.21572}, { 19.1643, 0.645643, 16.2456, 7.18544, 4.3709, 21.4072, 0, 0, 5.21404}, { 19.2214, 0.5946, 17.6444, 6.9089, 4.461, 24.7008, 1.6029, 87.4825, 5.0694}, { 19.1514, 0.597922, 17.2535, 6.80639, 4.47128, 20.2521, 0, 0, 5.11937}, { 19.1624, 0.5476, 18.5596, 6.3776, 4.2948, 25.8499, 2.0396, 92.8029, 4.9391}, { 19.1045, 0.551522, 18.1108, 6.3247, 3.78897, 17.3595, 0, 0, 4.99635}, { 19.1889, 5.8303, 19.1005, 0.5031, 4.4585, 26.8909, 2.4663, 83.9571, 4.7821}, { 19.1094, 0.5036, 19.0548, 5.8378, 4.5648, 23.3752, 0.487, 62.2061, 4.7861}, { 18.9333, 5.764, 19.7131, 0.4655, 3.4182, 14.0049, 0.0193, -0.7583, 3.9182}, { 19.6418, 5.3034, 19.0455, 0.4607, 5.0371, 27.9074, 2.6827, 75.2825, 4.5909}, { 18.9755, 0.467196, 18.933, 5.22126, 5.10789, 19.5902, 0.288753, 55.5113, 4.69626}, { 19.8685, 5.44853, 19.0302, 0.467973, 2.41253, 14.1259, 0, 0, 4.69263}, { 19.9644, 4.81742, 19.0138, 0.420885, 6.14487, 28.5284, 2.5239, 70.8403, 4.352}, { 20.1472, 4.347, 18.9949, 0.3814, 7.5138, 27.766, 2.2735, 66.8776, 4.0712}, { 20.2332, 4.3579, 18.997, 0.3815, 7.8069, 29.5259, 2.8868, 84.9304, 4.0714}, { 20.2933, 3.9282, 19.0298, 0.344, 8.9767, 26.4659, 1.99, 64.2658, 3.7118}, { 20.3892, 3.569, 19.1062, 0.3107, 10.662, 24.3879, 1.4953, 213.904, 3.3352}, { 20.3524, 3.552, 19.1278, 0.3086, 10.2821, 23.7128, 0.9615, 59.4565, 3.2791}, { 20.3361, 3.216, 19.297, 0.2756, 10.888, 20.2073, 2.6959, 167.202, 2.7731}, { 20.1807, 3.21367, 19.1136, 0.28331, 10.9054, 20.0558, 0.77634, 51.746, 3.02902}, { 20.578, 2.94817, 19.599, 0.244475, 11.3727, 18.7726, 3.28719, 133.124, 2.14678}, { 20.2489, 2.9207, 19.3763, 0.250698, 11.6323, 17.8211, 0.336048, 54.9453, 2.4086}, { 21.1671, 2.81219, 19.7695, 0.226836, 11.8513, 17.6083, 3.33049, 127.113, 1.86264}, { 20.8036, 2.77691, 19.559, 0.23154, 11.9369, 16.5408, 0.612376, 43.1692, 2.09013}, { 20.3235, 2.65941, 19.8186, 0.21885, 12.1233, 15.7992, 0.144583, 62.2355, 1.5918}, { 22.044, 2.77393, 19.6697, 0.222087, 12.3856, 16.7669, 2.82428, 143.644, 2.0583}, { 21.3727, 2.6452, 19.7491, 0.214299, 12.1329, 15.323, 0.97518, 36.4065, 1.77132}, { 20.9413, 2.54467, 20.0539, 0.202481, 12.4668, 14.8137, 0.296689, 45.4643, 1.24285}, { 22.6845, 2.66248, 19.6847, 0.210628, 12.774, 15.885, 2.85137, 137.903, 1.98486}, { 21.961, 2.52722, 19.9339, 0.199237, 12.12, 14.1783, 1.51031, 30.8717, 1.47588}, { 23.3405, 2.5627, 19.6095, 0.202088, 13.1235, 15.1009, 2.87516, 132.721, 2.02876}, { 22.5527, 2.4174, 20.1108, 0.185769, 12.0671, 13.1275, 2.07492, 27.4491, 1.19499}, { 24.0042, 2.47274, 19.4258, 0.196451, 13.4396, 14.3996, 2.89604, 128.007, 2.20963}, { 23.1504, 2.31641, 20.2599, 0.174081, 11.9202, 12.1571, 2.71488, 24.8242, 0.954586}, { 24.6274, 2.3879, 19.0886, 0.1942, 13.7603, 13.7546, 2.9227, 123.174, 2.5745}, { 24.0063, 2.27783, 19.9504, 0.17353, 11.8034, 11.6096, 3.87243, 26.5156, 1.36389}, { 23.7497, 2.22258, 20.3745, 0.16394, 11.8509, 11.311, 3.26503, 22.9966, 0.759344}, { 25.0709, 2.25341, 19.0798, 0.181951, 13.8518, 12.9331, 3.54545, 101.398, 2.4196}, { 24.3466, 2.13553, 20.4208, 0.155525, 11.8708, 10.5782, 3.7149, 21.7029, 0.645089}, { 25.8976, 2.24256, 18.2185, 0.196143, 14.3167, 12.6648, 2.95354, 115.362, 3.58324}, { 24.9559, 2.05601, 20.3271, 0.149525, 12.2471, 10.0499, 3.773, 21.2773, 0.691967}, { 26.507, 2.1802, 17.6383, 0.202172, 14.5596, 12.1899, 2.96577, 111.874, 4.29728}, { 25.5395, 1.9804, 20.2861, 0.143384, 11.9812, 9.34972, 4.50073, 19.581, 0.68969}, { 26.9049, 2.07051, 17.294, 0.19794, 14.5583, 11.4407, 3.63837, 92.6566, 4.56796}, { 26.1296, 1.91072, 20.0994, 0.139358, 11.9788, 8.80018, 4.93676, 18.5908, 0.852795}, { 27.6563, 2.07356, 16.4285, 0.223545, 14.9779, 11.3604, 2.98233, 105.703, 5.92046}, { 26.722, 1.84659, 19.7748, 0.13729, 12.1506, 8.36225, 5.17379, 17.8974, 1.17613}, { 28.1819, 2.02859, 15.8851, 0.238849, 15.1542, 10.9975, 2.98706, 102.961, 1.63929}, { 27.3083, 1.78711, 19.332, 0.136974, 12.3339, 7.96778, 5.38348, 17.2922, 1.63929}, { 28.6641, 1.9889, 15.4345, 0.257119, 15.3087, 10.6647, 2.98963, 100.417, 7.56672}, { 28.1209, 1.78503, 17.6817, 0.15997, 13.3335, 8.18304, 5.14657, 20.39, 3.70983}, { 27.8917, 1.73272, 18.7614, 0.13879, 12.6072, 7.64412, 5.47647, 16.8153, 2.26001}, { 28.9476, 1.90182, 15.2208, 9.98519, 15.1, 0.261033, 3.71601, 84.3298, 7.97628}, { 28.4628, 1.68216, 18.121, 0.142292, 12.8429, 7.33727, 5.59415, 16.3535, 2.97573}, { 29.144, 1.83262, 15.1726, 9.5999, 14.7586, 0.275116, 4.30013, 72.029, 8.58154}, { 28.8131, 1.59136, 18.4601, 0.128903, 12.7285, 6.76232, 5.59927, 14.0366, 2.39699}, { 29.2024, 1.77333, 15.2293, 9.37046, 14.5135, 0.295977, 4.76492, 63.3644, 9.24354}, { 29.1587, 1.50711, 18.8407, 0.116741, 12.8268, 6.31524, 5.38695, 12.4244, 1.78555}, { 29.0818, 1.72029, 15.43, 9.2259, 14.4327, 0.321703, 5.11982, 57.056, 9.8875}, { 29.4936, 1.42755, 19.3763, 0.104621, 13.0544, 5.93667, 5.06412, 11.1972, 1.01074}, { 28.7621, 1.67191, 15.7189, 9.09227, 14.5564, 0.3505, 5.44174, 52.0861, 10.472}, { 28.1894, 1.62903, 16.155, 8.97948, 14.9305, 0.382661, 5.67589, 48.1647, 11.0005}, { 30.419, 1.37113, 15.2637, 6.84706, 14.7458, 0.165191, 5.06795, 18.003, 6.49804}, { 27.3049, 1.59279, 16.7296, 8.86553, 15.6115, 0.417916, 5.83377, 45.0011, 11.4722}, { 30.4156, 1.34323, 15.862, 7.10909, 13.6145, 0.204633, 5.82008, 20.3254, 8.27903}, { 30.7058, 1.30923, 15.5512, 6.71983, 14.2326, 0.167252, 5.53672, 17.4911, 6.96824}, { 27.0059, 1.51293, 17.7639, 8.81174, 15.7131, 0.424593, 5.7837, 38.6103, 11.6883}, { 29.8429, 1.32927, 16.7224, 7.38979, 13.2153, 0.263297, 6.35234, 22.9426, 9.85329}, { 30.9612, 1.24813, 15.9829, 6.60834, 13.7348, 0.16864, 5.92034, 16.9392, 7.39534}, { 16.8819, 0.4611, 18.5913, 8.6216, 25.5582, 1.4826, 5.86, 36.3956, 12.0658}, { 28.0109, 1.35321, 17.8204, 7.7395, 14.3359, 0.356752, 6.58077, 26.4043, 11.2299}, { 30.6886, 1.2199, 16.9029, 6.82872, 12.7801, 0.212867, 6.52354, 18.659, 9.0968}, { 20.6809, 0.545, 19.0417, 8.4484, 21.6575, 1.5729, 5.9676, 38.3246, 12.6089}, { 25.0853, 1.39507, 18.4973, 7.65105, 16.8883, 0.443378, 6.48216, 28.2262, 12.0205}, { 29.5641, 1.21152, 18.06, 7.05639, 12.8374, 0.284738, 6.89912, 20.7482, 10.6268}, { 27.5446, 0.65515, 19.1584, 8.70751, 15.538, 1.96347, 5.52593, 45.8149, 13.1746}, { 21.3985, 1.4711, 20.4723, 0.517394, 18.7478, 7.43463, 6.82847, 28.8482, 12.5258}, { 30.8695, 1.1008, 18.3481, 6.53852, 11.9328, 0.219074, 7.00574, 17.2114, 9.8027}, { 31.0617, 0.6902, 13.0637, 2.3576, 18.442, 8.618, 5.9696, 47.2579, 13.4118}, { 21.7886, 1.3366, 19.5682, 0.488383, 19.1406, 6.7727, 7.01107, 23.8132, 12.4734}, { 32.1244, 1.00566, 18.8003, 6.10926, 12.0175, 0.147041, 6.96886, 14.714, 8.08428}, { 33.3689, 0.704, 12.951, 2.9238, 16.5877, 8.7937, 6.4692, 48.0093, 13.5782}, { 21.8053, 1.2356, 19.5026, 6.24149, 19.1053, 0.469999, 7.10295, 20.3185, 12.4711}, { 33.5364, 0.91654, 25.0946, 0.39042, 19.2497, 5.71414, 6.91555, 12.8285, 6.7994}, { 34.6726, 0.700999, 15.4733, 3.55078, 13.1138, 9.55642, 7.02588, 47.0045, 13.677}, { 35.3163, 0.68587, 19.0211, 3.97458, 9.49887, 11.3824, 7.42518, 45.4715, 13.7108}, { 35.5631, 0.6631, 21.2816, 4.0691, 8.0037, 14.0422, 7.4433, 44.2473, 13.6905}, { 35.9299, 0.646453, 23.0547, 4.17619, 12.1439, 23.1052, 2.11253, 150.645, 13.7247}, { 35.763, 0.616341, 22.9064, 3.87135, 12.4739, 19.9887, 3.21097, 142.325, 13.6211}, { 35.215, 0.604909, 21.67, 3.5767, 7.91342, 12.601, 7.65078, 29.8436, 13.5431}, { 35.6597, 0.589092, 23.1032, 3.65155, 12.5977, 18.599, 4.08655, 117.02, 13.5266}, { 35.1736, 0.579689, 22.1112, 3.41437, 8.19216, 12.9187, 7.05545, 25.9443, 13.4637}, { 35.5645, 0.563359, 23.4219, 3.46204, 12.7473, 17.8309, 4.80703, 99.1722, 13.4314}, { 35.1007, 0.555054, 22.4418, 3.24498, 9.78554, 13.4661, 5.29444, 23.9533, 13.376}, { 35.8847, 0.547751, 23.2948, 3.41519, 14.1891, 16.9235, 4.17287, 105.251, 13.4287}, { 36.0228, 0.5293, 23.4128, 3.3253, 14.9491, 16.0927, 4.188, 100.613, 13.3966}, { 35.5747, 0.52048, 22.5259, 3.12293, 12.2165, 12.7148, 5.37073, 26.3394, 13.3092}, { 35.3715, 0.516598, 22.5326, 3.05053, 12.0291, 12.5723, 4.7984, 23.4582, 13.2671}, { 34.8509, 0.507079, 22.7584, 2.8903, 14.0099, 13.1767, 1.21457, 25.2017, 13.1665}, { 36.1874, 0.511929, 23.5964, 3.25396, 15.6402, 15.3622, 4.1855, 97.4908, 13.3573}, { 35.7074, 0.502322, 22.613, 3.03807, 12.9898, 12.1449, 5.43227, 25.4928, 13.2544}, { 35.5103, 0.498626, 22.5787, 2.96627, 12.7766, 11.9484, 4.92159, 22.7502, 13.2116}, { 35.0136, 0.48981, 22.7286, 2.81099, 14.3884, 12.33, 1.75669, 22.6581, 13.113}, { 36.5254, 0.499384, 23.8083, 3.26371, 16.7707, 14.9455, 3.47947, 105.98, 13.3812}, { 35.84, 0.484938, 22.7169, 2.96118, 13.5807, 11.5331, 5.66016, 24.3992, 13.1991}, { 35.6493, 0.481422, 22.646, 2.8902, 13.3595, 11.316, 5.18831, 21.8301, 13.1555}, { 35.1736, 0.473204, 22.7181, 2.73848, 14.7635, 11.553, 2.28678, 20.9303, 13.0582}, { 36.6706, 0.483629, 24.0992, 3.20647, 17.3415, 14.3136, 3.49331, 102.273, 13.3592}, { 36.6488, 0.465154, 24.4096, 3.08997, 17.399, 13.4346, 4.21665, 88.4834, 13.2887}, { 36.7881, 0.451018, 24.7736, 3.04619, 17.8919, 12.8946, 4.23284, 86.003, 13.2754}, { 36.9185, 0.437533, 25.1995, 3.00775, 18.3317, 12.4044, 4.24391, 83.7881, 13.2674}, }; #endif diff --git a/src/USER-DIFFRACTION/fix_saed_vtk.h b/src/USER-DIFFRACTION/fix_saed_vtk.h index 294b003b0..fa379e721 100644 --- a/src/USER-DIFFRACTION/fix_saed_vtk.h +++ b/src/USER-DIFFRACTION/fix_saed_vtk.h @@ -1,188 +1,188 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(saed/vtk,FixSAEDVTK) #else #ifndef LMP_FIX_SAED_VTK_H #define LMP_FIX_SAED_VTK_H #include #include "fix.h" namespace LAMMPS_NS { class FixSAEDVTK : public Fix { public: FixSAEDVTK(class LAMMPS *, int, char **); ~FixSAEDVTK(); int setmask(); void init(); void setup(int); void end_of_step(); double compute_vector(int); void reset_timestep(bigint); private: int me,nvalues; int nrepeat,nfreq,irepeat; bigint nvalid; int which; char *ids; FILE *fp; int nrows; int ave,nwindow,nsum,startstep; int overwrite; long filepos; int norm,iwindow,window_limit; double *vector; double *vector_total; double **vector_list; void invoke_scalar(bigint); void invoke_vector(bigint); void options(int, char **); bigint nextvalid(); class ComputeSAED *compute_saed; double Zone[3]; // Zone axis to view SAED double R_Ewald; // Radius of Ewald sphere (distance units) double lambda; // Radiation wavelenght (distance units) double dK[3]; // spacing of reciprocal points in each dimension int Knmax[3]; // maximum integer value for K points in each dimension int Knmin[3]; // minimum integer value for K points in each dimension int KnSlice[6]; // min 0-2 max 2-5 hkl index using zone double Kmax; // Maximum reciprocal distance to explore double c[3]; // Parameters controlling resolution of reciprocal space explored double dR_Ewald; // Thickness of Ewald sphere slice double prd_inv[3]; // Inverse spacing of unit cell char *filename; // user-specified file int nOutput; int Dim[3]; bool manual; // Turn on manual recpiprocal map }; } #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: Compute ID for fix ave/time does not exist Self-explanatory. E: Fix ID for fix ave/time does not exist Self-explanatory. E: Invalid fix ave/time off column Self-explanatory. E: Fix ave/time compute does not calculate a scalar Self-explanatory. E: Fix ave/time compute does not calculate a vector Self-explanatory. E: Fix ave/time compute vector is accessed out-of-range The index for the vector is out of bounds. E: Fix ave/time compute does not calculate an array Self-explanatory. E: Fix ave/time compute array is accessed out-of-range An index for the array is out of bounds. E: Fix ave/time fix does not calculate a scalar Self-explanatory. E: Fix ave/time fix does not calculate a vector Self-explanatory. E: Fix ave/time fix vector is accessed out-of-range The index for the vector is out of bounds. E: Fix for fix ave/time not computed at compatible time Fixes generate their values on specific timesteps. Fix ave/time is requesting a value on a non-allowed timestep. E: Fix ave/time fix does not calculate an array Self-explanatory. E: Fix ave/time fix array is accessed out-of-range An index for the array is out of bounds. E: Variable name for fix ave/time does not exist Self-explanatory. E: Fix ave/time variable is not equal-style variable Self-explanatory. E: Fix ave/time cannot use variable with vector mode Variables produce scalar values. E: Fix ave/time columns are inconsistent lengths Self-explanatory. E: Fix ave/time cannot set output array intensive/extensive from these inputs One of more of the vector inputs has individual elements which are flagged as intensive or extensive. Such an input cannot be flagged as all intensive/extensive when turned into an array by fix ave/time. E: Cannot open fix ave/time file %s The specified file cannot be opened. Check that the path and name are correct. E: Fix ave/time missed timestep You cannot reset the timestep to a value beyond where the fix expects to next perform averaging. */ diff --git a/src/USER-DPD/fix_dpd_energy.h b/src/USER-DPD/fix_dpd_energy.h index 9be41c3b9..89ba84c08 100644 --- a/src/USER-DPD/fix_dpd_energy.h +++ b/src/USER-DPD/fix_dpd_energy.h @@ -1,52 +1,52 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(dpd/energy,FixDPDenergy) #else #ifndef LMP_FIX_DPDE_H #define LMP_FIX_DPDE_H #include "fix.h" namespace LAMMPS_NS { class FixDPDenergy : public Fix { public: FixDPDenergy(class LAMMPS *, int, char **); virtual ~FixDPDenergy() {} int setmask(); virtual void initial_integrate(int); virtual void final_integrate(); protected: class PairDPDfdtEnergy *pairDPDE; }; } #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. */ diff --git a/src/USER-DPD/fix_rx.h b/src/USER-DPD/fix_rx.h index c35c9afab..35998963e 100644 --- a/src/USER-DPD/fix_rx.h +++ b/src/USER-DPD/fix_rx.h @@ -1,195 +1,195 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(rx,FixRX) #else #ifndef LMP_FIX_RX_H #define LMP_FIX_RX_H #include "fix.h" typedef int (*fnptr)(double, const double *, double *, void *); namespace LAMMPS_NS { enum { ODE_LAMMPS_RK4, ODE_LAMMPS_RKF45 }; class FixRX : public Fix { public: FixRX(class LAMMPS *, int, char **); ~FixRX(); int setmask(); void post_constructor(); virtual void init(); void init_list(int, class NeighList *); virtual void setup_pre_force(int); virtual void pre_force(int); protected: int pack_reverse_comm(int, int, double *); void unpack_reverse_comm(int, int *, double *); int pack_forward_comm(int , int *, double *, int, int *); void unpack_forward_comm(int , int , double *); class NeighList *list; double tmpArg; int *mol2param; // mapping from molecule to parameters int nreactions; // # of stored parameter sets int maxparam; // max # of parameter sets struct Param { double cp; int ispecies; char *name; // names of unique molecules and interaction type }; Param *params; // parameter set for an I-J-K interaction int nspecies; void read_file(char *); void setupParams(); double *Arr, *nArr, *Ea, *tempExp; double **stoich, **stoichReactants, **stoichProducts; double *kR; //!< Classic Runge-Kutta 4th-order stepper. void rk4(int,double*); //!< Runge-Kutta-Fehlberg ODE Solver. void rkf45(int,double*); //!< Runge-Kutta-Fehlberg ODE stepper function. void rkf45_step (const int neq, const double h, double y[], double y_out[], double rwk[], void* v_param); //!< Initial step size estimation for the Runge-Kutta-Fehlberg ODE solver. int rkf45_h0 (const int neq, const double t, const double t_stop, const double hmin, const double hmax, double& h0, double y[], double rwk[], void* v_params); class PairDPDfdtEnergy *pairDPDE; double *dpdThetaLocal; double *sumWeights; void computeLocalTemperature(); int localTempFlag,wtFlag,odeIntegrationFlag; double sigFactor; int rhs(double, const double *, double *, void *); int rhs_dense (double, const double *, double *, void *); // Sparse stoichiometric matrix storage format and methods. bool useSparseKinetics; //SparseKinetics sparseKinetics; void initSparse(void); int rhs_sparse(double, const double *, double *, void *) const; int sparseKinetics_maxReactants; // table inner cutoff The local density inner is greater than the inner cutoff E: Only LOOKUP and LINEAR table styles have been implemented for pair multi/lucy/rx 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: Unknown table style in pair_style command Self-explanatory E: Illegal number of pair table entries There must be at least 2 table entries. E: Illegal pair_coeff command All pair coefficients must be set in the data file or by the pair_coeff command before running a simulation. E: PairMultiLucyRX requires a fix rx command The fix rx command must come before the pair style command in the input file E: There are no rx species specified There must be at least one species specified through the fix rx command E: Invalid pair table length Length of read-in pair table is invalid 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: Cannot open file %s The specified file cannot be opened. Check that the path and name are correct. E: Did not find keyword in table file Keyword used in pair_coeff command was not found in table file. E: Invalid keyword in pair table parameters Keyword used in list of table parameters is not recognized. E: Pair table parameters did not set N List of pair table parameters must include N setting. */ diff --git a/src/USER-DPD/pair_table_rx.h b/src/USER-DPD/pair_table_rx.h index c6afe6a8d..34b9fd75c 100644 --- a/src/USER-DPD/pair_table_rx.h +++ b/src/USER-DPD/pair_table_rx.h @@ -1,173 +1,173 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(table/rx,PairTableRX) #else #ifndef LMP_PAIR_TABLE_RX_H #define LMP_PAIR_TABLE_RX_H #include "pair.h" namespace LAMMPS_NS { class PairTableRX : public Pair { public: PairTableRX(class LAMMPS *); virtual ~PairTableRX(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); void write_restart_settings(FILE *); void read_restart_settings(FILE *); double single(int, int, int, int, double, double, double, double &); void *extract(const char *, int &); protected: enum{LOOKUP,LINEAR,SPLINE,BITMAP}; int tabstyle,tablength; struct Table { int ninput,rflag,fpflag,match,ntablebits; int nshiftbits,nmask; double rlo,rhi,fplo,fphi,cut; double *rfile,*efile,*ffile; double *e2file,*f2file; double innersq,delta,invdelta,deltasq6; double *rsq,*drsq,*e,*de,*f,*df,*e2,*f2; }; int ntables; Table *tables; int **tabindex; void allocate(); void read_table(Table *, char *, char *); void param_extract(Table *, char *); void bcast_table(Table *); void spline_table(Table *); void compute_table(Table *); void null_table(Table *); void free_table(Table *); void spline(double *, double *, int, double, double, double *); double splint(double *, double *, double *, int, double); int nspecies; char *site1, *site2; int isite1, isite2; void getMixingWeights(int, double &, double &, double &, double &); bool fractionalWeighting; }; } #endif #endif /* ERROR/WARNING messages: E: Pair distance < table inner cutoff Two atoms are closer together than the pairwise table allows. E: Pair distance > table outer cutoff Two atoms are further apart than the pairwise table allows. 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: Unknown table style in pair_style command Style of table is invalid for use with pair_style table command. E: PairTableRX requires a fix rx command The fix rx command must come before the pair style command in the input file E: There are no rx species specified There must be at least one species specified through the fix rx command E: Site1 name not recognized in pair coefficients The site1 keyword does not match the species keywords specified throug the fix rx command E: Illegal number of pair table entries There must be at least 2 table entries. E: Invalid pair table length Length of read-in pair table is invalid E: Invalid pair table cutoff Cutoffs in pair_coeff command are not valid with read-in pair table. E: Bitmapped table in file does not match requested table Setting for bitmapped table in pair_coeff command must match table in file exactly. 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: Cannot open file %s The specified file cannot be opened. Check that the path and name are correct. If the file is a compressed file, also check that the gzip executable can be found and run. E: Did not find keyword in table file Keyword used in pair_coeff command was not found in table file. E: Bitmapped table is incorrect length in table file Number of table entries is not a correct power of 2. E: Invalid keyword in pair table parameters Keyword used in list of table parameters is not recognized. E: Pair table parameters did not set N List of pair table parameters must include N setting. E: Pair table cutoffs must all be equal to use with KSpace When using pair style table with a long-range KSpace solver, the cutoffs for all atom type pairs must all be the same, since the long-range solver starts at that cutoff. E: The number of molecules in CG particle is less than 10*DBL_EPSILON Self-explanatory. Check the species concentrations have been properly set and check the reaction kinetic solver parameters in fix rx to more for sufficient accuracy. */ diff --git a/src/USER-MANIFOLD/fix_nve_manifold_rattle.h b/src/USER-MANIFOLD/fix_nve_manifold_rattle.h index 71aa1aed9..2bc821ab0 100644 --- a/src/USER-MANIFOLD/fix_nve_manifold_rattle.h +++ b/src/USER-MANIFOLD/fix_nve_manifold_rattle.h @@ -1,172 +1,172 @@ -/* ---------------------------------------------------------------------- +/* -*- 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. ----------------------------------------------------------------------- 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! ------------------------------------------------------------------------- */ #ifdef FIX_CLASS FixStyle(nve/manifold/rattle,FixNVEManifoldRattle) #else #ifndef LMP_FIX_NVE_MANIFOLD_RATTLE_H #define LMP_FIX_NVE_MANIFOLD_RATTLE_H #include "fix.h" #include "manifold.h" namespace LAMMPS_NS { // namespace user_manifold { class FixNVEManifoldRattle : public Fix { public: struct statistics { statistics() : x_iters(0), v_iters(0), x_iters_per_atom(0), v_iters_per_atom(0), natoms(0), dofs_removed(0), last_out(0) {} double x_iters, v_iters; double x_iters_per_atom; double v_iters_per_atom; int natoms; int dofs_removed; bigint last_out; }; FixNVEManifoldRattle(LAMMPS *, int &, char **, int = 1); virtual ~FixNVEManifoldRattle(); // All this stuff is interface, so you DO need to implement them. // Just delegate them to the workhorse classes. virtual int setmask(); virtual void initial_integrate(int); virtual void final_integrate(); virtual void init(); virtual void reset_dt(); virtual void end_of_step(); virtual int dof(int); virtual void setup(int){} // Not needed for fixNVE but is for fixNVT virtual double memory_usage(); protected: int nevery, next_output; double dtv, dtf; double tolerance; int max_iter; char **tstrs; int *tvars; int *tstyle; int *is_var; statistics stats; int update_style; int nvars; user_manifold::manifold *ptr_m; void print_stats( const char * ); int was_var( const char * ); virtual void update_var_params(); virtual void rattle_manifold_x( double *, double *, double *, double, double, tagint ); virtual void rattle_manifold_v( double *, double *, double *, double, tagint ); virtual void nve_x_rattle(int, int); virtual void nve_v_rattle(int, int); }; } #endif // LMP_FIX_NVE_MANIFOLD_RATTLE_H #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: There is no manifold named ... Self-explanatory. You requested a manifold whose name was not registered at the factory. E: Manifold pointer was NULL for some reason! This indicates a bug. The factory was unable to properly create the requested manifold even though it was registered. Send the maintainer an e-mail. E: Manifold ... needs at least ... argument(s)! Self-explanatory. Provide enough arguments for the proper creating of the requested manifold. E: Parameter pointer was NULL! This indicates a bug. The array that contains the parameters could not be allocated. Send the maintainer an e-mail. E: Could not allocate space for arg! One of the arguments provided was too long (it contained too many characters) E: Option ... needs ... argument(s): Self-explanatory. Read the documentation of this fix properly. E: Illegal fix nve/manifold/rattle command! Option ... not recognized! Self-explanatory. The given option(s) do not exist. E: Variable name for fix nve/manifold/rattle does not exist Self-explanatory. E: Variable for fix nve/manifold/rattle is invalid style fix nve/manifold/rattle only supports equal style variables. */ diff --git a/src/USER-MANIFOLD/fix_nvt_manifold_rattle.h b/src/USER-MANIFOLD/fix_nvt_manifold_rattle.h index a9d3e3122..144cda379 100644 --- a/src/USER-MANIFOLD/fix_nvt_manifold_rattle.h +++ b/src/USER-MANIFOLD/fix_nvt_manifold_rattle.h @@ -1,155 +1,155 @@ -/* ---------------------------------------------------------------------- +/* -*- 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. ----------------------------------------------------------------------- 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! ------------------------------------------------------------------------- */ #ifdef FIX_CLASS FixStyle(nvt/manifold/rattle,FixNVTManifoldRattle) #else #ifndef LMP_FIX_NVT_MANIFOLD_RATTLE_H #define LMP_FIX_NVT_MANIFOLD_RATTLE_H #include "fix_nve_manifold_rattle.h" /* FixNVTManifoldRattle works by wrapping some Nose-Hoover thermostat routines around the time integration functions of FixNVEManifoldRattle. */ namespace LAMMPS_NS { // namespace user_manifold { class FixNVTManifoldRattle : public FixNVEManifoldRattle { public: FixNVTManifoldRattle(LAMMPS *, int, char **, int = 1); virtual ~FixNVTManifoldRattle(); virtual void initial_integrate(int); virtual void final_integrate(); virtual void init(); virtual void reset_dt(); virtual int setmask(); virtual void setup(int); // Not needed for fixNVE but is for fixNVT virtual double memory_usage(); protected: void compute_temp_target(); void nhc_temp_integrate(); void nh_v_temp(); double dthalf, dt4, dt8; char *id_temp; class Compute* temperature; double t_start,t_stop, t_period; double t_current,t_target,ke_target; double t_freq, drag, tdrag_factor; double boltz,nktv2p,tdof; double *eta,*eta_dot; double *eta_dotdot; double *eta_mass; int mtchain; double factor_eta; int which, got_temp; const char *fix_id; }; } #endif // LMP_FIX_NVE_MANIFOLD_RATTLE_H #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: There is no manifold named ... Self-explanatory. You requested a manifold whose name was not registered at the factory. E: Manifold pointer was NULL for some reason! This indicates a bug. The factory was unable to properly create the requested manifold even though it was registered. Send the maintainer an e-mail. E: Manifold ... needs at least ... argument(s)! Self-explanatory. Provide enough arguments for the proper creating of the requested manifold. E: Parameter pointer was NULL! This indicates a bug. The array that contains the parameters could not be allocated. Send the maintainer an e-mail. E: Could not allocate space for arg! One of the arguments provided was too long (it contained too many characters) E: Option ... needs ... argument(s): Self-explanatory. Read the documentation of this fix properly. E: Illegal fix nve/manifold/rattle command! Option ... not recognized! Self-explanatory. The given option(s) do not exist. E: Variable name for fix nve/manifold/rattle does not exist Self-explanatory. E: Variable for fix nve/manifold/rattle is invalid style fix nve/manifold/rattle only supports equal style variables. */ diff --git a/src/USER-MANIFOLD/manifold.h b/src/USER-MANIFOLD/manifold.h index b89e765a6..f0d56ffd8 100644 --- a/src/USER-MANIFOLD/manifold.h +++ b/src/USER-MANIFOLD/manifold.h @@ -1,100 +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. ----------------------------------------------------------------------- This file is a part of the USER-MANIFOLD package. This package allows LAMMPS to perform MD simulations of particles constrained on a manifold (i.e., a 2D subspace of the 3D simulation box). It achieves this using the RATTLE constraint algorithm applied to single-particle constraint functions g(xi,yi,zi) = 0 and their derivative (i.e. the normal of the manifold) n = grad(g). It is very easy to add your own manifolds to the current zoo (we now have sphere, a dendritic spine approximation, a 2D plane (for testing purposes) and a wave-y plane. See the README file for more info. Stefan Paquay, stefanpaquay@gmail.com Applied Physics/Theory of Polymers and Soft Matter, Eindhoven University of Technology (TU/e), The Netherlands Thanks to Remy Kusters at TU/e for testing. This software is distributed under the GNU General Public License. ------------------------------------------------------------------------- */ #ifndef LMP_MANIFOLD_H #define LMP_MANIFOLD_H #include "pointers.h" #include namespace LAMMPS_NS { namespace user_manifold { // Abstract base class. class manifold : protected Pointers { public: manifold(class LAMMPS* lmp) : Pointers(lmp), params(NULL){ } virtual ~manifold(){ delete[] params; } virtual double g( const double * ) = 0; virtual void n( const double *, double * ) = 0; // Variant of g that computes n at the same time. virtual double g_and_n( const double *x, double *nn ) { this->n(x,nn); return g(x); } virtual const char *id() = 0; virtual void set_atom_id( tagint a_id ){} virtual int nparams() = 0; // double *get_params(){ return params; }; // Overload if any initialization depends on params: virtual void post_param_init(){} virtual void checkup(){} // Some diagnostics... double *params; }; // Some utility functions that are templated, so I implement them // here in the header. template< unsigned int size > inline double infnorm( double *vect ) { double largest = fabs( vect[0] ); for( unsigned int i = 1; i < size; ++i ){ double c = fabs( vect[i] ); largest = ( c > largest ) ? c : largest; } return largest; } inline double dot( double *a, double *b ){ return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; } } // namespace LAMMPS_NS } #endif // LMP_MANIFOLD_H diff --git a/src/USER-MANIFOLD/manifold_factory.h b/src/USER-MANIFOLD/manifold_factory.h index a2f21861e..7fdd0a6de 100644 --- a/src/USER-MANIFOLD/manifold_factory.h +++ b/src/USER-MANIFOLD/manifold_factory.h @@ -1,110 +1,110 @@ -/* ---------------------------------------------------------------------- +/* -*- 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. ----------------------------------------------------------------------- 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! ------------------------------------------------------------------------- */ #ifndef LMP_MANIFOLD_FACTORY_H #define LMP_MANIFOLD_FACTORY_H #include "manifold.h" #include /* * Defining USE_PHONY_LAMMPS makes sure that none of the LAMMPS classes are * included/compiled. This is done in order to allow other programs to use * the manifold_factory without compiling all of LAMMPS itself. The relevant * classes/functions are replaced with dummy ones defined in this #ifdef-block: */ #ifdef USE_PHONY_LAMMPS # ifdef __GNUG__ # warning Not compiling actual LAMMPS classes! # endif struct Error { void all(const char *fname, int line, const char* msg) { fprintf(stderr,"ERROR: %s (%s:%d)",msg,fname,line); std::terminate(); } void one(const char *fname, int line, const char* msg) { fprintf(stderr,"ERROR: %s (%s:%d)",msg,fname,line); std::terminate(); } }; struct LAMMPS { }; struct Pointers { Pointers(LAMMPS *) : error( &e ){} Error e; Error *error; }; static FILE *screen = fopen("/dev/stdout","w"); #define FLERR __FILE__,__LINE__ // Equivalent to definition in pointers.h #endif // USE_PHONY_LAMMPS /* Here the actual implementation of LAMMPS-related functions begins. */ namespace LAMMPS_NS { namespace user_manifold { // Templated, so needs to be in header. template void make_manifold_if( manifold **man_ptr, const char *name, LAMMPS *lmp, int narg, char **arg ) { if( strcmp( m_type::type(), name ) == 0 ){ if( *man_ptr == NULL ){ *man_ptr = new m_type(lmp, narg, arg); } } } manifold* create_manifold(const char *, LAMMPS *, int , char ** ); } // namespace user_manifold } // namespace LAMMPS_NS #endif // LMP_MANIFOLD_FACTORY_H diff --git a/src/USER-MANIFOLD/manifold_gaussian_bump.h b/src/USER-MANIFOLD/manifold_gaussian_bump.h index f3401a4a3..f31e2a4bf 100644 --- a/src/USER-MANIFOLD/manifold_gaussian_bump.h +++ b/src/USER-MANIFOLD/manifold_gaussian_bump.h @@ -1,82 +1,82 @@ -/* ---------------------------------------------------------------------- +/* -*- 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. ----------------------------------------------------------------------- This file is a part of the USER-MANIFOLD package. This package allows LAMMPS to perform MD simulations of particles constrained on a manifold (i.e., a 2D subspace of the 3D simulation box). It achieves this using the RATTLE constraint algorithm applied to single-particle constraint functions g(xi,yi,zi) = 0 and their derivative (i.e. the normal of the manifold) n = grad(g). It is very easy to add your own manifolds to the current zoo (we now have sphere, a dendritic spine approximation, a 2D plane (for testing purposes) and a wave-y plane. See the README file for more info. Stefan Paquay, spaquay@brandeis.edu Brandeis University, Waltham, MA, USA. This package was mainly developed at Applied Physics/Theory of Polymers and Soft Matter, Eindhoven University of Technology (TU/e), The Netherlands Thanks to Remy Kusters at TU/e for testing. This software is distributed under the GNU General Public License. ------------------------------------------------------------------------- */ #ifndef LMP_MANIFOLD_GAUSSIAN_BUMP_H #define LMP_MANIFOLD_GAUSSIAN_BUMP_H #include "manifold.h" namespace LAMMPS_NS { namespace user_manifold { // A Gaussian bump with a smoothed decay to flat 2D. class manifold_gaussian_bump : public manifold { public: enum { NPARAMS = 4 }; manifold_gaussian_bump(class LAMMPS*, int, char **) : manifold(lmp) {} virtual ~manifold_gaussian_bump(){} virtual double g( const double * ); virtual void n( const double *, double * ); // Variant of g that computes n at the same time. virtual double g_and_n( const double *x, double *nn ); static const char* type(){ return "gaussian_bump"; } virtual const char *id() { return type(); } virtual int nparams(){ return NPARAMS; } virtual void post_param_init(); private: // Some private constants: double aa, bb, cc, dd, AA, ll, ll2, f_at_rc, fp_at_rc; double rc1, rc2, rc12, rc22, dr, inv_dr; double gaussian_bump ( double ); double gaussian_bump_x2 ( double ); double gaussian_bump_der( double ); }; } } #endif // LMP_MANIFOLD_GAUSSIAN_BUMP_H diff --git a/src/USER-MISC/compute_cnp_atom.cpp b/src/USER-MISC/compute_cnp_atom.cpp index 89568c673..f479486b7 100644 --- a/src/USER-MISC/compute_cnp_atom.cpp +++ b/src/USER-MISC/compute_cnp_atom.cpp @@ -1,331 +1,331 @@ /* ---------------------------------------------------------------------- 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. Common Neighbor Parameter as proposed in: Tsuzuki, Branicio, Rino, Comput Phys Comm, 177, 518 (2007) Cite: http://dx.doi.org/10.1063/1.2197987 ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Paulo Branicio (University of Southern California) branicio@usc.edu ------------------------------------------------------------------------- */ #include #include #include #include "compute_cnp_atom.h" #include "atom.h" #include "update.h" #include "modify.h" #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" #include "force.h" #include "pair.h" #include "comm.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; //define maximum values #define MAXNEAR 24 #define MAXCOMMON 12 enum{NCOMMON}; /* ---------------------------------------------------------------------- */ ComputeCNPAtom::ComputeCNPAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg), - nearest(NULL), nnearest(NULL), cnpv(NULL) + list(NULL), nearest(NULL), nnearest(NULL), cnpv(NULL) { if (narg != 4) error->all(FLERR,"Illegal compute cnp/atom command"); peratom_flag = 1; size_peratom_cols = 0; double cutoff = force->numeric(FLERR,arg[3]); if (cutoff < 0.0) error->all(FLERR,"Illegal compute cnp/atom command"); cutsq = cutoff*cutoff; // apply check for single type atoms in compute group int lasttype = -1; int n = -1; for (int i=0; i < atom->nlocal; ++i) { if (atom->mask[i] & groupbit) { if (lasttype != atom->type[i]) { lasttype = atom->type[i]; ++n; } } } int all_n = 0; MPI_Allreduce(&n,&all_n,1,MPI_INT,MPI_MAX,world); if (all_n > 0) error->warning(FLERR,"Compute cnp/atom requested on multi-type system"); nmax = 0; } /* ---------------------------------------------------------------------- */ ComputeCNPAtom::~ComputeCNPAtom() { memory->destroy(nearest); memory->destroy(nnearest); memory->destroy(cnpv); } /* ---------------------------------------------------------------------- */ void ComputeCNPAtom::init() { if (force->pair == NULL) error->all(FLERR,"Compute cnp/atom requires a pair style be defined"); if (sqrt(cutsq) > force->pair->cutforce) error->all(FLERR,"Compute cnp/atom cutoff is longer than pairwise cutoff"); if (2.0*sqrt(cutsq) > force->pair->cutforce + neighbor->skin && comm->me == 0) error->warning(FLERR,"Compute cnp/atom cutoff may be too large to find " "ghost atom neighbors"); int count = 0; for (int i = 0; i < modify->ncompute; i++) if (strcmp(modify->compute[i]->style,"cnp/atom") == 0) count++; if (count > 1 && comm->me == 0) error->warning(FLERR,"More than one compute cnp/atom defined"); // need an occasional full neighbor list int irequest = neighbor->request(this,instance_me); neighbor->requests[irequest]->pair = 0; neighbor->requests[irequest]->compute = 1; neighbor->requests[irequest]->half = 0; neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->occasional = 1; } /* ---------------------------------------------------------------------- */ void ComputeCNPAtom::init_list(int id, NeighList *ptr) { list = ptr; } /* ---------------------------------------------------------------------- */ void ComputeCNPAtom::compute_peratom() { int i,j,k,ii,jj,kk,m,n,inum,jnum,inear,jnear; int firstflag,ncommon; int *ilist,*jlist,*numneigh,**firstneigh; int onenearest[MAXNEAR]; int common[MAXCOMMON]; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double xjtmp,yjtmp,zjtmp,rjkx,rjky,rjkz; invoked_peratom = update->ntimestep; // grow arrays if necessary if (atom->nmax > nmax) { memory->destroy(nearest); memory->destroy(nnearest); memory->destroy(cnpv); nmax = atom->nmax; memory->create(nearest,nmax,MAXNEAR,"cnp:nearest"); memory->create(nnearest,nmax,"cnp:nnearest"); memory->create(cnpv,nmax,"cnp:cnp_cnpv"); vector_atom = cnpv; } // invoke full neighbor list (will copy or build if necessary) neighbor->build_one(list); inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; // find the neigbors of each atom within cutoff using full neighbor list // nearest[] = atom indices of nearest neighbors, up to MAXNEAR // do this for all atoms, not just compute group // since CNP calculation requires neighbors of neighbors double **x = atom->x; int *mask = atom->mask; int nlocal = atom->nlocal; int nerror = 0; for (ii = 0; ii < inum; ii++) { i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; jlist = firstneigh[i]; jnum = numneigh[i]; n = 0; 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; if (rsq < cutsq) { if (n < MAXNEAR) nearest[i][n++] = j; else { nerror++; break; } } } nnearest[i] = n; } // warning message int nerrorall; MPI_Allreduce(&nerror,&nerrorall,1,MPI_INT,MPI_SUM,world); if (nerrorall && comm->me == 0) { char str[128]; sprintf(str,"Too many neighbors in CNP for %d atoms",nerrorall); error->warning(FLERR,str,0); } // compute CNP value for each atom in group // only performed if # of nearest neighbors = 12 or 14 (fcc,hcp) nerror = 0; for (ii = 0; ii < inum; ii++) { i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; // reset cnpv cnpv[i] = 0.0; // skip computation of cnpv for atoms outside the compute group if (!(mask[i] & groupbit)) continue; // loop over nearest neighbors of I to build cnp data structure // cnp[k][NCOMMON] = # of common neighbors of I with each of its neighbors for (m = 0; m < nnearest[i]; m++) { j = nearest[i][m]; xjtmp = x[j][0]; yjtmp = x[j][1]; zjtmp = x[j][2]; // common = list of neighbors common to atom I and atom J // if J is an owned atom, use its near neighbor list to find them // if J is a ghost atom, use full neighbor list of I to find them // in latter case, must exclude J from I's neighbor list // find common neighbors of i and j using near neighbor list if (j < nlocal) { firstflag = 1; ncommon = 0; for (inear = 0; inear < nnearest[i]; inear++) for (jnear = 0; jnear < nnearest[j]; jnear++) if (nearest[i][inear] == nearest[j][jnear]) { if (ncommon < MAXCOMMON) common[ncommon++] = nearest[i][inear]; else if (firstflag) { nerror++; firstflag = 0; } } // find common neighbors of i and j using full neighbor list } else { jlist = firstneigh[i]; jnum = numneigh[i]; n = 0; for (kk = 0; kk < jnum; kk++) { k = jlist[kk]; k &= NEIGHMASK; if (k == j) continue; delx = xjtmp - x[k][0]; dely = yjtmp - x[k][1]; delz = zjtmp - x[k][2]; rsq = delx*delx + dely*dely + delz*delz; if (rsq < cutsq) { if (n < MAXNEAR) onenearest[n++] = k; else break; } } firstflag = 1; ncommon = 0; for (inear = 0; inear < nnearest[i]; inear++) for (jnear = 0; (jnear < n) && (n < MAXNEAR); jnear++) if (nearest[i][inear] == onenearest[jnear]) { if (ncommon < MAXCOMMON) common[ncommon++] = nearest[i][inear]; else if (firstflag) { nerror++; firstflag = 0; } } } // Calculate and update sum |Rik+Rjk|ˆ2 rjkx = 0.0; rjky = 0.0; rjkz = 0.0; for (kk = 0; kk < ncommon; kk++) { k = common[kk]; rjkx += 2.0*x[k][0] - xjtmp - xtmp; rjky += 2.0*x[k][1] - yjtmp - ytmp; rjkz += 2.0*x[k][2] - zjtmp - ztmp; } // update cnpv with summed (valuejk) cnpv[i] += rjkx*rjkx + rjky*rjky + rjkz*rjkz; // end of loop over j atoms } // normalize cnp by the number of nearest neighbors cnpv[i] = cnpv[i] / nnearest[i]; // end of loop over i atoms } // warning message MPI_Allreduce(&nerror,&nerrorall,1,MPI_INT,MPI_SUM,world); if (nerrorall && comm->me == 0) { char str[128]; sprintf(str,"Too many common neighbors in CNP %d times",nerrorall); error->warning(FLERR,str); } } /* ---------------------------------------------------------------------- memory usage of local atom-based array ------------------------------------------------------------------------- */ double ComputeCNPAtom::memory_usage() { double bytes = nmax * sizeof(int); bytes += nmax * MAXNEAR * sizeof(int); bytes += nmax * sizeof(double); return bytes; } diff --git a/src/USER-MISC/fix_filter_corotate.h b/src/USER-MISC/fix_filter_corotate.h index 3f8e8bba4..67e3fb4f0 100644 --- a/src/USER-MISC/fix_filter_corotate.h +++ b/src/USER-MISC/fix_filter_corotate.h @@ -1,137 +1,137 @@ -/* ---------------------------------------------------------------------- +/* -*- 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: Lukas Fath (KIT) some subroutines are from fix_shake.cpp ------------------------------------------------------------------------- */ #ifdef FIX_CLASS FixStyle(filter/corotate,FixFilterCorotate) #else #ifndef LMP_FIX_FILTER_COROTATE_H #define LMP_FIX_FILTER_COROTATE_H #include "fix.h" namespace LAMMPS_NS { class FixFilterCorotate : public Fix { public: FixFilterCorotate(class LAMMPS *, int, char **); ~FixFilterCorotate(); void setup(int); void setup_pre_neighbor(); void pre_neighbor(); void setup_pre_force_respa(int,int); // void setup_post_force_respa(int,int); void pre_force_respa(int, int, int); void post_force_respa(int, int, int); void init(); int setmask(); double compute_array(int,int); int pack_forward_comm(int, int *, double *, int, int *); void unpack_forward_comm(int, int, double *); void grow_arrays(int ); double memory_usage(); void copy_arrays(int, int, int); void set_arrays(int); void update_arrays(int, int); int pack_exchange(int, double *); int unpack_exchange(int, double *); protected: int me,nprocs; int flevel; //filtered respa level double **help2; //temp derivative double **x_store; //temp for atom->x double *g; //temp for derivative double*n1,*n2,*n3, *del1, *del2,*del3; double**dn1dx,**dn2dx,**dn3dx; int *bond_flag,*angle_flag; // bond/angle types to constrain int *type_flag; // constrain bonds to these types double *mass_list; // constrain bonds to these masses int nmass; // # of masses in mass_list int molecular; // copy of atom->molecular double *bond_distance,*angle_distance; // constraint distances int nlevels_respa; // copies of needed rRESPA variables double **x,**v,**f; // local ptrs to atom class quantities double *mass,*rmass; int *type; int nlocal; // atom-based arrays int *shake_flag; // 0 if atom not in SHAKE cluster // 1 = size 3 angle cluster // 2,3,4 = size of bond-only cluster tagint **shake_atom; // global IDs of atoms in cluster // central atom is 1st // lowest global ID is 1st for size 2 int **shake_type; // bondtype of each bond in cluster // for angle cluster, 3rd value // is angletype int *nshake; // count int *list; // list of clusters to SHAKE int nlist,maxlist; // size and max-size of list double ***clist_derv; //stores derivative double **clist_q0; //stores reference config int *clist_nselect1, *clist_nselect2; //stores length of each selec. list int **clist_select1, **clist_select2; //stores selection lists void find_clusters(); int masscheck(double); void filter_inner(); void filter_outer(); void general_cluster(int,int); void stats(); int bondtype_findset(int, tagint, tagint, int); int angletype_findset(int, tagint, tagint, int); // callback functions for ring communication static void ring_bonds(int, char *, void *); static void ring_nshake(int, char *, void *); static void ring_shake(int, char *, void *); int sgn(double val) { return (0 < val) - (val < 0); }; }; } #endif #endif diff --git a/src/USER-MISC/fix_ti_spring.h b/src/USER-MISC/fix_ti_spring.h index 57c0d3299..13f1236a8 100644 --- a/src/USER-MISC/fix_ti_spring.h +++ b/src/USER-MISC/fix_ti_spring.h @@ -1,95 +1,95 @@ -/* ---------------------------------------------------------------------- +/* -*- 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 authors: Rodrigo Freitas (UC Berkeley) - rodrigof@berkeley.edu Mark Asta (UC Berkeley) - mdasta@berkeley.edu Maurice de Koning (Unicamp/Brazil) - dekoning@ifi.unicamp.br ------------------------------------------------------------------------- */ #ifdef FIX_CLASS FixStyle(ti/spring,FixTISpring) #else #ifndef LMP_FIX_TI_SPRING_H #define LMP_FIX_TI_SPRING_H #include "fix.h" namespace LAMMPS_NS { class FixTISpring : public Fix { public: FixTISpring(class LAMMPS *, int, char **); ~FixTISpring(); int setmask(); void init(); void setup(int); void min_setup(int); void post_force(int); void post_force_respa(int, int, int); void min_post_force(int); void initial_integrate(int); double compute_scalar(); double compute_vector(int); double memory_usage(); void grow_arrays(int); void copy_arrays(int, int, 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(); private: double switch_func(double); // Switching function. double dswitch_func(double); // Switching function derivative. double k; // Spring constant. double espring; // Springs energies. double **xoriginal; // Original coords of atoms. double lambda; // Coupling parameter. double dlambda; // Lambda variation with t. double linfo[2]; // Current lambda status. bigint t_switch; // Total switching steps. bigint t_equil; // Equilibration time. bigint t0; // Initial time. int sf; // Switching function option. int nlevels_respa; }; } #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: Illegal fix ti/spring switching function 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/USER-MISC/fix_ttm_mod.h b/src/USER-MISC/fix_ttm_mod.h index 3415baf5b..21f6e57e0 100644 --- a/src/USER-MISC/fix_ttm_mod.h +++ b/src/USER-MISC/fix_ttm_mod.h @@ -1,88 +1,88 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(ttm/mod,FixTTMMod) #else #ifndef LMP_FIX_TTM_MOD_H #define LMP_FIX_TTM_MOD_H #include "fix.h" namespace LAMMPS_NS { struct el_heat_capacity_thermal_conductivity { double el_heat_capacity; double el_thermal_conductivity; }; class FixTTMMod : public Fix { public: FixTTMMod(class LAMMPS *, int, char **); ~FixTTMMod(); int setmask(); void init(); void setup(int); void post_force(int); void post_force_respa(int, int, int); void post_force_setup(int); void post_force_respa_setup(int, int, int); void end_of_step(); void reset_dt(); void write_restart(FILE *); void restart(char *); int pack_restart(int, double *); void unpack_restart(int, int); int size_restart(int); int maxsize_restart(); double memory_usage(); void grow_arrays(int); double compute_vector(int); private: int me; int nfileevery; int nlevels_respa; int seed; class RanMars *random; FILE *fp; int nxnodes,nynodes,nznodes,total_nnodes; int ***nsum; int ***nsum_all,***T_initial_set; double *gfactor1,*gfactor2,*ratio; double **flangevin; double ***T_electron,***T_electron_old,***T_electron_first; double ***sum_vsq,***sum_mass_vsq; double ***sum_vsq_all,***sum_mass_vsq_all; double ***net_energy_transfer,***net_energy_transfer_all; double gamma_p,gamma_s,v_0,v_0_sq; int skin_layer,surface_l,surface_r,t_surface_l,t_surface_r; int movsur; double esheat_0,esheat_1,esheat_2,esheat_3,esheat_4,C_limit,electronic_density; double el_th_diff,T_damp; double intensity,width,duration,surface_double; double mult_factor,ttm_dt; double pres_factor,free_path,ionic_density; double electron_temperature_min; el_heat_capacity_thermal_conductivity el_properties(double); double el_sp_heat_integral(double); void read_initial_electron_temperatures(FILE *); }; } #endif #endif diff --git a/src/USER-MISC/improper_distance.h b/src/USER-MISC/improper_distance.h index 6301e6897..cff96c6d9 100644 --- a/src/USER-MISC/improper_distance.h +++ b/src/USER-MISC/improper_distance.h @@ -1,47 +1,47 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ #ifdef IMPROPER_CLASS ImproperStyle(distance,ImproperDistance) #else #ifndef LMP_IMPROPER_DISTANCE_H #define LMP_IMPROPER_DISTANCE_H #include #include "improper.h" namespace LAMMPS_NS { class ImproperDistance : public Improper { public: ImproperDistance(class LAMMPS *); ~ImproperDistance(); void compute(int, int); void coeff(int, char **); void write_restart(FILE *); void read_restart(FILE *); private: double *k,*chi; void allocate(); }; } #endif #endif diff --git a/src/USER-MISC/pair_buck_mdf.h b/src/USER-MISC/pair_buck_mdf.h index c0ecceeea..4f9bac634 100644 --- a/src/USER-MISC/pair_buck_mdf.h +++ b/src/USER-MISC/pair_buck_mdf.h @@ -1,73 +1,73 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(buck/mdf,PairBuckMDF) #else #ifndef LMP_PAIR_BUCK_MDF_H #define LMP_PAIR_BUCK_MDF_H #include "pair.h" namespace LAMMPS_NS { class PairBuckMDF : public Pair { public: PairBuckMDF(class LAMMPS *); virtual ~PairBuckMDF(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); void write_restart_settings(FILE *); void read_restart_settings(FILE *); double single(int, int, int, int, double, double, double, double &); void *extract(const char *, int &); protected: double cut_global,cut_inner_global; double **cut,**cut_inner,**cut_inner_sq; double **a,**rho,**c; double **rhoinv,**buck1,**buck2,**offset; void allocate(); }; } #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: 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. */ diff --git a/src/USER-MISC/pair_edip_multi.h b/src/USER-MISC/pair_edip_multi.h index e55916f79..fd94594d9 100644 --- a/src/USER-MISC/pair_edip_multi.h +++ b/src/USER-MISC/pair_edip_multi.h @@ -1,113 +1,113 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(edip/multi,PairEDIPMulti) #else #ifndef LMP_PAIR_EDIP_MULTI_H #define LMP_PAIR_EDIP_MULTI_H #include "pair.h" namespace LAMMPS_NS { class PairEDIPMulti : public Pair { public: PairEDIPMulti(class LAMMPS *); virtual ~PairEDIPMulti(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); void init_style(); protected: struct Param { double A, B;//coefficients for pair interaction I-J double cutoffA;//cut-off distance for pair interaction I-J double cutoffC;//lower cut-off distance for calculating Z_I double alpha;//coefficient for calculating Z_I double beta;//attractive term for pair I-J double sigma;//cut-off coefficient for pair I-J double rho;//pair I-J double gamma;//coefficient for three-body interaction I-J-K double eta, lambda;//coefficients for function h(l,Z) double mu, Q0;//coefficients for function Q(Z) double u1, u2, u3, u4;//coefficients for function tau(Z) double cutsq; int ielement,jelement,kelement; }; double *preForceCoord; double cutmax; // max cutoff for all elements int nelements; // # of unique elements char **elements; // names of unique elements int ***elem2param; // mapping from element triplets to parameters int *map; // mapping from atom types to elements int nparams; // # of stored parameter sets int maxparam; // max # of parameter sets Param *params; // parameter set for an I-J-K interaction // max number of interaction per atom for f(Z) environment potential static const int leadDimInteractionList = 64; void allocate(); void allocatePreLoops(void); void deallocatePreLoops(void); void read_file(char *); void setup(); void edip_pair(double, double, Param *, double &, double &, double &); void edip_fc(double, Param *, double &, double &); void edip_fcut2(double, Param *, double &, double &); void edip_tau(double, Param *, double &, double &); void edip_h(double, double, Param *, double &, double &, double &); void edip_fcut3(double, Param *, double &, double &); double vec3_dot(double x[3], double y[3]) { return x[0]*y[0] + x[1]*y[1] + x[2]*y[2]; } void vec3_add(double k1, double x[3], double k2, double y[3], double *z) { z[0] = k1 * x[0] + k2 * y[0]; z[1] = k1 * x[1] + k2 * y[1]; z[2] = k1 * x[2] + k2 * y[2]; } //dr_ij=r_j - r_i //dr_ik=r_k - r_i void costheta_d(double *dr_ij, double r_ij, double *dr_ik, double r_ik, double *dri, double *drj, double *drk) { double costheta; costheta = vec3_dot(dr_ij, dr_ik) / r_ij / r_ik; vec3_add(1 / r_ij / r_ik, dr_ik, -costheta / r_ij / r_ij, dr_ij, drj); vec3_add(1 / r_ij / r_ik, dr_ij, -costheta / r_ik / r_ik, dr_ik, drk); vec3_add(-1, drj, -1, drk, dri); } }; } #endif #endif diff --git a/src/USER-MISC/pair_kolmogorov_crespi_z.h b/src/USER-MISC/pair_kolmogorov_crespi_z.h index 3a81e571e..caa5dac86 100644 --- a/src/USER-MISC/pair_kolmogorov_crespi_z.h +++ b/src/USER-MISC/pair_kolmogorov_crespi_z.h @@ -1,83 +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 PAIR_CLASS PairStyle(kolmogorov/crespi/z,PairKolmogorovCrespiZ) #else #ifndef LMP_PAIR_KolmogorovCrespiZ_H #define LMP_PAIR_KolmogorovCrespiZ_H #include "pair.h" namespace LAMMPS_NS { class PairKolmogorovCrespiZ : public Pair { public: PairKolmogorovCrespiZ(class LAMMPS *); virtual ~PairKolmogorovCrespiZ(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); protected: int me; struct Param { double z0,C0,C2,C4,C,delta,lambda,A,S; double delta2inv,z06; int ielement,jelement; }; Param *params; // parameter set for I-J interactions char **elements; // names of unique elements int **elem2param; // mapping from element pairs to parameters int *map; // mapping from atom types to elements int nelements; // # of unique elements int nparams; // # of stored parameter sets int maxparam; // max # of parameter sets double cut_global; double **cut; double **offset; void read_file( char * ); void allocate(); }; } #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: 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. */ diff --git a/src/USER-MISC/pair_lennard_mdf.h b/src/USER-MISC/pair_lennard_mdf.h index 6fefe6fc3..c4ffc80cd 100644 --- a/src/USER-MISC/pair_lennard_mdf.h +++ b/src/USER-MISC/pair_lennard_mdf.h @@ -1,69 +1,69 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(lennard/mdf,PairLJ_AB_MDF) #else #ifndef LMP_PAIR_LJ_AB_MDF_H #define LMP_PAIR_LJ_AB_MDF_H #include "pair.h" namespace LAMMPS_NS { class PairLJ_AB_MDF : public Pair { public: PairLJ_AB_MDF(class LAMMPS *); virtual ~PairLJ_AB_MDF(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); void write_restart_settings(FILE *); void read_restart_settings(FILE *); double single(int, int, int, int, double, double, double, double &); void *extract(const char *, int &); protected: double cut_global,cut_inner_global; double **cut,**cut_inner,**cut_inner_sq; double **aparm,**bparm; double **lj1,**lj2,**lj3,**lj4; void allocate(); }; } #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. */ diff --git a/src/USER-MISC/pair_lj_mdf.h b/src/USER-MISC/pair_lj_mdf.h index f49020bf2..c6236a923 100644 --- a/src/USER-MISC/pair_lj_mdf.h +++ b/src/USER-MISC/pair_lj_mdf.h @@ -1,69 +1,69 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(lj/mdf,PairLJMDF) #else #ifndef LMP_PAIR_LJ_MDF_H #define LMP_PAIR_LJ_MDF_H #include "pair.h" namespace LAMMPS_NS { class PairLJMDF : public Pair { public: PairLJMDF(class LAMMPS *); virtual ~PairLJMDF(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); void write_restart_settings(FILE *); void read_restart_settings(FILE *); double single(int, int, int, int, double, double, double, double &); void *extract(const char *, int &); protected: double cut_global,cut_inner_global; double **cut,**cut_inner,**cut_inner_sq; double **epsilon,**sigma; double **lj1,**lj2,**lj3,**lj4; void allocate(); }; } #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. */ diff --git a/src/USER-MISC/pair_meam_spline.h b/src/USER-MISC/pair_meam_spline.h index 620025467..d3554f056 100644 --- a/src/USER-MISC/pair_meam_spline.h +++ b/src/USER-MISC/pair_meam_spline.h @@ -1,304 +1,304 @@ -/* ---------------------------------------------------------------------- +/* -*- 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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- see LLNL copyright notice at bottom of file ------------------------------------------------------------------------- */ #ifdef PAIR_CLASS PairStyle(meam/spline,PairMEAMSpline) #else #ifndef LMP_PAIR_MEAM_SPLINE_H #define LMP_PAIR_MEAM_SPLINE_H #include "pair.h" namespace LAMMPS_NS { // Set this to 1 if you intend to use MEAM potentials with // non-uniform spline knots. // Set this to 0 if you intend to use only MEAM potentials with // spline knots on a uniform grid. // // With SUPPORT_NON_GRID_SPLINES == 0, the code runs about 50% faster. #define SPLINE_MEAM_SUPPORT_NON_GRID_SPLINES 0 class PairMEAMSpline : public Pair { public: PairMEAMSpline(class LAMMPS *); virtual ~PairMEAMSpline(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void get_coeff(double *, double *); double pair_density(int ); double three_body_density(int ); void init_style(); void init_list(int, class NeighList *); double init_one(int, int); // helper functions for compute() int ij_to_potl(const int itype, const int jtype, const int ntypes) const { return jtype - 1 + (itype-1)*ntypes - (itype-1)*itype/2; } int i_to_potl(const int itype) const { return itype-1; } int pack_forward_comm(int, int *, double *, int, int *); void unpack_forward_comm(int, int, double *); int pack_reverse_comm(int, int, double *); void unpack_reverse_comm(int, int *, double *); double memory_usage(); protected: char **elements; // names of unique elements int *map; // mapping from atom types to elements int nelements; // # of unique elements class SplineFunction { public: /// Default constructor. SplineFunction() : X(NULL), Xs(NULL), Y(NULL), Y2(NULL), Ydelta(NULL), N(0) {} /// Destructor. ~SplineFunction() { delete[] X; delete[] Xs; delete[] Y; delete[] Y2; delete[] Ydelta; } /// Initialization of spline function. void init(int _N, double _deriv0, double _derivN) { N = _N; deriv0 = _deriv0; derivN = _derivN; // if (X) delete[] X; // if (Xs) delete[] Xs; // if (Y) delete[] Y; // if (Y2) delete[] Y2; // if (Ydelta) delete[] Ydelta; X = new double[N]; Xs = new double[N]; Y = new double[N]; Y2 = new double[N]; Ydelta = new double[N]; } /// Adds a knot to the spline. void setKnot(int n, double x, double y) { X[n] = x; Y[n] = y; } /// Returns the number of knots. int numKnots() const { return N; } /// Parses the spline knots from a text file. void parse(FILE* fp, Error* error, bool isNewFormat); /// Calculates the second derivatives of the cubic spline. void prepareSpline(Error* error); /// Evaluates the spline function at position x. inline double eval(double x) const { x -= xmin; if(x <= 0.0) { // Left extrapolation. return Y[0] + deriv0 * x; } else if(x >= xmax_shifted) { // Right extrapolation. return Y[N-1] + derivN * (x - xmax_shifted); } else { #if SPLINE_MEAM_SUPPORT_NON_GRID_SPLINES // Do interval search. int klo = 0; int khi = N-1; while(khi - klo > 1) { int k = (khi + klo) / 2; if(Xs[k] > x) khi = k; else klo = k; } double h = Xs[khi] - Xs[klo]; // Do spline interpolation. double a = (Xs[khi] - x)/h; double b = 1.0 - a; // = (x - X[klo])/h return a * Y[klo] + b * Y[khi] + ((a*a*a - a) * Y2[klo] + (b*b*b - b) * Y2[khi])*(h*h)/6.0; #else // For a spline with regular grid, we directly calculate the interval X is in. int klo = (int)(x / h); int khi = klo + 1; double a = Xs[khi] - x; double b = h - a; return Y[khi] - a * Ydelta[klo] + ((a*a - hsq) * a * Y2[klo] + (b*b - hsq) * b * Y2[khi]); #endif } } /// Evaluates the spline function and its first derivative at position x. inline double eval(double x, double& deriv) const { x -= xmin; if(x <= 0.0) { // Left extrapolation. deriv = deriv0; return Y[0] + deriv0 * x; } else if(x >= xmax_shifted) { // Right extrapolation. deriv = derivN; return Y[N-1] + derivN * (x - xmax_shifted); } else { #if SPLINE_MEAM_SUPPORT_NON_GRID_SPLINES // Do interval search. int klo = 0; int khi = N-1; while(khi - klo > 1) { int k = (khi + klo) / 2; if(Xs[k] > x) khi = k; else klo = k; } double h = Xs[khi] - Xs[klo]; // Do spline interpolation. double a = (Xs[khi] - x)/h; double b = 1.0 - a; // = (x - X[klo])/h deriv = (Y[khi] - Y[klo]) / h + ((3.0*b*b - 1.0) * Y2[khi] - (3.0*a*a - 1.0) * Y2[klo]) * h / 6.0; return a * Y[klo] + b * Y[khi] + ((a*a*a - a) * Y2[klo] + (b*b*b - b) * Y2[khi]) * (h*h) / 6.0; #else // For a spline with regular grid, we directly calculate the interval X is in. int klo = (int)(x / h); int khi = klo + 1; double a = Xs[khi] - x; double b = h - a; deriv = Ydelta[klo] + ((3.0*b*b - hsq) * Y2[khi] - (3.0*a*a - hsq) * Y2[klo]); return Y[khi] - a * Ydelta[klo] + ((a*a - hsq) * a * Y2[klo] + (b*b - hsq) * b * Y2[khi]); #endif } } /// Returns the number of bytes used by this function object. double memory_usage() const { return sizeof(*this) + sizeof(X[0]) * N * 3; } /// Returns the cutoff radius of this function. double cutoff() const { return X[N-1]; } /// Writes a Gnuplot script that plots the spline function. void writeGnuplot(const char* filename, const char* title = NULL) const; /// Broadcasts the spline function parameters to all processors. void communicate(MPI_Comm& world, int me); private: double* X; // Positions of spline knots double* Xs; // Shifted positions of spline knots double* Y; // Function values at spline knots double* Y2; // Second derivatives at spline knots double* Ydelta; // If this is a grid spline, Ydelta[i] = (Y[i+1]-Y[i])/h int N; // Number of spline knots double deriv0; // First derivative at knot 0 double derivN; // First derivative at knot (N-1) double xmin; // The beginning of the interval on which the spline function is defined. double xmax; // The end of the interval on which the spline function is defined. int isGridSpline;// Indicates that all spline knots are on a regular grid. double h; // The distance between knots if this is a grid spline with equidistant knots. double hsq; // The squared distance between knots if this is a grid spline with equidistant knots. double xmax_shifted; // The end of the spline interval after it has been shifted to begin at X=0. }; /// Helper data structure for potential routine. struct MEAM2Body { int tag; // holds the index of the second atom (j) double r; double f, fprime; double del[3]; }; SplineFunction* phis; // Phi_i(r_ij) SplineFunction* rhos; // Rho_ij(r_ij) SplineFunction* fs; // f_i(r_ij) SplineFunction* Us; // U_i(rho) SplineFunction* gs; // g_ij(cos_theta) double* zero_atom_energies; // Shift embedding energy by this value to make it zero for a single atom in vacuum. double cutoff; // The cutoff radius double* Uprime_values; // Used for temporary storage of U'(rho) values int nmax; // Size of temporary array. int maxNeighbors; // The last maximum number of neighbors a single atoms has. MEAM2Body* twoBodyInfo; // Temporary array. void read_file(const char* filename); void allocate(); }; } #endif #endif /* ---------------------------------------------------------------------- * Spline-based Modified Embedded Atom method (MEAM) potential routine. * * Copyright (2011) Lawrence Livermore National Security, LLC. * Produced at the Lawrence Livermore National Laboratory. * Written by Alexander Stukowski (). * LLNL-CODE-525797 All rights reserved. * * 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) version 2, dated June 1991. * * 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 terms and conditions of the * GNU General Public License for more details. * * Our Preamble Notice * A. This notice is required to be provided under our contract with the * U.S. Department of Energy (DOE). This work was produced at the * Lawrence Livermore National Laboratory under Contract No. * DE-AC52-07NA27344 with the DOE. * * B. Neither the United States Government nor Lawrence Livermore National * Security, LLC nor any of their employees, makes any warranty, express or * implied, or assumes any liability or responsibility for the accuracy, * completeness, or usefulness of any information, apparatus, product, or * process disclosed, or represents that its use would not infringe * privately-owned rights. * * C. Also, reference herein to any specific commercial products, process, * or services by trade name, trademark, manufacturer or otherwise does not * necessarily constitute or imply its endorsement, recommendation, or * favoring by the United States Government or Lawrence Livermore National * Security, LLC. The views and opinions of authors expressed herein do not * necessarily state or reflect those of the United States Government or * Lawrence Livermore National Security, LLC, and shall not be used for * advertising or product endorsement purposes. * * See file 'pair_spline_meam.cpp' for history of changes. ------------------------------------------------------------------------- */ diff --git a/src/USER-MISC/pair_momb.h b/src/USER-MISC/pair_momb.h index 95b750cb2..e08b81aa3 100644 --- a/src/USER-MISC/pair_momb.h +++ b/src/USER-MISC/pair_momb.h @@ -1,77 +1,77 @@ -/* ---------------------------------------------------------------------- +/* -*- 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. ------------------------------------------------------------------------- Contributed by Kristen Fichthorn, Tonnam Balankura, Ya Zhou @ Penn State University ------------------------------------------------------------------------- */ #ifdef PAIR_CLASS PairStyle(momb,PairMomb) #else #ifndef LMP_PAIR_MOMB_H #define LMP_PAIR_MOMB_H #include "pair.h" namespace LAMMPS_NS { class PairMomb : public Pair { public: PairMomb(class LAMMPS *); virtual ~PairMomb(); virtual void compute(int, int); virtual void settings(int, char **); void coeff(int, char **); virtual double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); void write_restart_settings(FILE *); void read_restart_settings(FILE *); virtual double single(int, int, int, int, double, double, double, double &); protected: double cut_global; double **cut; double sscale,dscale; double **d0,**alpha,**r0,**c,**rr; double **morse1; double **offset; void allocate(); }; } #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: 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. */ diff --git a/src/USER-NETCDF/dump_netcdf.h b/src/USER-NETCDF/dump_netcdf.h index 036df3f05..b86f294d3 100644 --- a/src/USER-NETCDF/dump_netcdf.h +++ b/src/USER-NETCDF/dump_netcdf.h @@ -1,106 +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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Lars Pastewka (University of Freiburg) ------------------------------------------------------------------------- */ #if defined(LMP_HAS_NETCDF) #ifdef DUMP_CLASS DumpStyle(netcdf,DumpNetCDF) #else #ifndef LMP_DUMP_NETCDF_H #define LMP_DUMP_NETCDFC_H #include "dump_custom.h" namespace LAMMPS_NS { const int NC_FIELD_NAME_MAX = 100; const int DUMP_NC_MAX_DIMS = 100; class DumpNetCDF : public DumpCustom { public: DumpNetCDF(class LAMMPS *, int, char **); virtual ~DumpNetCDF(); virtual void write(); private: // per-atoms quantities (positions, velocities, etc.) struct nc_perat_t { int dims; // number of dimensions int field[DUMP_NC_MAX_DIMS]; // field indices corresponding to the dim. char name[NC_FIELD_NAME_MAX]; // field name int var; // NetCDF variable bool constant; // is this property per file (not per frame) int ndumped; // number of enties written for this prop. }; int framei; // current frame index int blocki; // current block index int ndata; // number of data blocks to expect bigint ntotalgr; // # of atoms int n_perat; // # of netcdf per-atom properties nc_perat_t *perat; // per-atom properties int *thermovar; // NetCDF variables for thermo output bool double_precision; // write everything as double precision bool thermo; // write thermo output to netcdf file bigint n_buffer; // size of buffer int *int_buffer; // buffer for passing data to netcdf double *double_buffer; // buffer for passing data to netcdf int ncid; int frame_dim; int spatial_dim; int Voigt_dim; int atom_dim; int cell_spatial_dim; int cell_angular_dim; int label_dim; int spatial_var; int cell_spatial_var; int cell_angular_var; int time_var; int cell_origin_var; int cell_lengths_var; int cell_angles_var; virtual void openfile(); void closefile(); virtual void write_header(bigint); virtual void write_data(int, double *); void write_prmtop(); virtual int modify_param(int, char **); void ncerr(int, const char *, int); }; } #endif #endif #endif /* defined(LMP_HAS_NETCDF) */ diff --git a/src/USER-NETCDF/dump_netcdf_mpiio.h b/src/USER-NETCDF/dump_netcdf_mpiio.h index 10b0e800d..3ca52449a 100644 --- a/src/USER-NETCDF/dump_netcdf_mpiio.h +++ b/src/USER-NETCDF/dump_netcdf_mpiio.h @@ -1,105 +1,105 @@ -/* ---------------------------------------------------------------------- +/* -*- 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: Lars Pastewka (University of Freiburg) ------------------------------------------------------------------------- */ #if defined(LMP_HAS_PNETCDF) #ifdef DUMP_CLASS DumpStyle(netcdf/mpiio,DumpNetCDFMPIIO) #else #ifndef LMP_DUMP_NETCDF_MPIIO_H #define LMP_DUMP_NETCDF_MPIIO_H #include "dump_custom.h" namespace LAMMPS_NS { const int NC_MPIIO_FIELD_NAME_MAX = 100; const int DUMP_NC_MPIIO_MAX_DIMS = 100; class DumpNetCDFMPIIO : public DumpCustom { public: DumpNetCDFMPIIO(class LAMMPS *, int, char **); virtual ~DumpNetCDFMPIIO(); virtual void write(); private: // per-atoms quantities (positions, velocities, etc.) struct nc_perat_t { int dims; // number of dimensions int field[DUMP_NC_MPIIO_MAX_DIMS]; // field indices corresponding to the dim. char name[NC_MPIIO_FIELD_NAME_MAX]; // field name int var; // NetCDF variable }; typedef void (DumpNetCDFMPIIO::*funcptr_t)(void *); int framei; // current frame index int blocki; // current block index int ndata; // number of data blocks to expect bigint ntotalgr; // # of atoms int n_perat; // # of netcdf per-atom properties nc_perat_t *perat; // per-atom properties int *thermovar; // NetCDF variables for thermo output bool double_precision; // write everything as double precision bool thermo; // write thermo output to netcdf file bigint n_buffer; // size of buffer int *int_buffer; // buffer for passing data to netcdf double *double_buffer; // buffer for passing data to netcdf int ncid; int frame_dim; int spatial_dim; int Voigt_dim; int atom_dim; int cell_spatial_dim; int cell_angular_dim; int label_dim; int spatial_var; int cell_spatial_var; int cell_angular_var; int time_var; int cell_origin_var; int cell_lengths_var; int cell_angles_var; virtual void openfile(); void closefile(); void write_time_and_cell(); virtual void write_data(int, double *); void write_prmtop(); virtual int modify_param(int, char **); void ncerr(int, const char *, int); }; } #endif #endif #endif /* defined(LMP_HAS_PNETCDF) */ diff --git a/src/USER-OMP/fix_qeq_reax_omp.h b/src/USER-OMP/fix_qeq_reax_omp.h index 078ba3b9a..7565f0aff 100644 --- a/src/USER-OMP/fix_qeq_reax_omp.h +++ b/src/USER-OMP/fix_qeq_reax_omp.h @@ -1,76 +1,76 @@ -/* ---------------------------------------------------------------------- +/* -*- 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: Hasan Metin Aktulga, Purdue University (now at Lawrence Berkeley National Laboratory, hmaktulga@lbl.gov) Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and Algorithmic Techniques", Parallel Computing, in press. ------------------------------------------------------------------------- */ #ifdef FIX_CLASS FixStyle(qeq/reax/omp,FixQEqReaxOMP) #else #ifndef LMP_FIX_QEQ_REAX_OMP_H #define LMP_FIX_QEQ_REAX_OMP_H #include "fix_qeq_reax.h" namespace LAMMPS_NS { class FixQEqReaxOMP : public FixQEqReax { public: FixQEqReaxOMP(class LAMMPS *, int, char **); ~FixQEqReaxOMP(); virtual void init(); virtual void init_storage(); virtual void pre_force(int); virtual void post_constructor(); protected: double **b_temp; int do_aspc; int aspc_order, aspc_order_max; double aspc_omega; double * aspc_b; virtual void allocate_storage(); virtual void deallocate_storage(); virtual void init_matvec(); virtual void compute_H(); virtual int CG(double*,double*); virtual void sparse_matvec(sparse_matrix*,double*,double*); virtual void calculate_Q(); virtual void vector_sum(double*,double,double*,double,double*,int); virtual void vector_add(double*, double, double*,int); // dual CG support virtual int dual_CG(double*,double*,double*,double*); virtual void dual_sparse_matvec(sparse_matrix*,double*,double*,double*); virtual void dual_sparse_matvec(sparse_matrix*,double*,double*); }; } #endif #endif diff --git a/src/USER-OMP/pair_airebo_omp.cpp b/src/USER-OMP/pair_airebo_omp.cpp index 206e8e86e..13df13358 100644 --- a/src/USER-OMP/pair_airebo_omp.cpp +++ b/src/USER-OMP/pair_airebo_omp.cpp @@ -1,2815 +1,2811 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Axel Kohlmeyer (Temple U) ------------------------------------------------------------------------- */ #include #include "pair_airebo_omp.h" #include "atom.h" #include "comm.h" #include "error.h" #include "force.h" #include "memory.h" #include "my_page.h" #include "math_special.h" #include "neighbor.h" #include "neigh_list.h" #if defined(_OPENMP) #include #endif #include "suffix.h" using namespace LAMMPS_NS; using namespace MathSpecial; #define TOL 1.0e-9 /* ---------------------------------------------------------------------- */ PairAIREBOOMP::PairAIREBOOMP(LAMMPS *lmp) : PairAIREBO(lmp), ThrOMP(lmp, THR_PAIR) { suffix_flag |= Suffix::OMP; respa_enable = 0; } /* ---------------------------------------------------------------------- */ void PairAIREBOOMP::compute(int eflag, int vflag) { double pv0=0.0,pv1=0.0,pv2=0.0; if (eflag || vflag) { ev_setup(eflag,vflag); } else evflag = vflag_fdotr = vflag_atom = 0; REBO_neigh_thr(); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; const int inum = list->inum; #if defined(_OPENMP) #pragma omp parallel default(none) shared(eflag,vflag) reduction(+:pv0,pv1,pv2) #endif { int ifrom, ito, tid; loop_setup_thr(ifrom, ito, tid, inum, nthreads); ThrData *thr = fix->get_thr(tid); thr->timer(Timer::START); ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr); FREBO_thr(ifrom,ito,evflag,eflag,vflag_atom,&pv0,thr); if (ljflag) FLJ_thr(ifrom,ito,evflag,eflag,vflag_atom,&pv1,thr); if (torflag) TORSION_thr(ifrom,ito,evflag,eflag,&pv2,thr); thr->timer(Timer::PAIR); reduce_thr(this, eflag, vflag, thr); } // end of omp parallel region pvector[0] = pv0; pvector[1] = pv1; pvector[2] = pv2; } /* ---------------------------------------------------------------------- create REBO neighbor list from main neighbor list REBO neighbor list stores neighbors of ghost atoms ------------------------------------------------------------------------- */ void PairAIREBOOMP::REBO_neigh_thr() { const int nthreads = comm->nthreads; 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"); } #if defined(_OPENMP) #pragma omp parallel default(none) #endif { int i,j,ii,jj,n,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; const int allnum = list->inum + list->gnum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; #if defined(_OPENMP) const int tid = omp_get_thread_num(); #else const int tid = 0; #endif const int iidelta = 1 + allnum/nthreads; const int iifrom = tid*iidelta; const int iito = ((iifrom+iidelta)>allnum) ? allnum : (iifrom+iidelta); // store all REBO neighs of owned and ghost atoms // scan full neighbor list of I // each thread has its own page allocator MyPage &ipg = ipage[tid]; ipg.reset(); for (ii = iifrom; ii < iito; ii++) { i = ilist[ii]; n = 0; neighptr = ipg.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; ipg.vgot(n); if (ipg.status()) error->one(FLERR,"REBO list overflow, boost neigh_modify one"); } } } /* ---------------------------------------------------------------------- REBO forces and energy ------------------------------------------------------------------------- */ void PairAIREBOOMP::FREBO_thr(int ifrom, int ito, int evflag, int eflag, int vflag_atom, double *pv0, ThrData * const thr) { int i,j,k,m,ii,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; const double * const * const x = atom->x; double * const * const f = thr->get_f(); int *type = atom->type; tagint *tag = atom->tag; int nlocal = atom->nlocal; ilist = list->ilist; // two-body interactions from REBO neighbor list, skip half of them for (ii = ifrom; ii < ito; 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_thr(i,j,del,rij,VA,vflag_atom,thr); 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) *pv0 += evdwl = VR + bij*VA; if (evflag) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1, evdwl,0.0,fpair,delx,dely,delz,thr); } } } /* ---------------------------------------------------------------------- compute LJ forces and energy find 3- and 4-step paths between atoms I,J via REBO neighbor lists ------------------------------------------------------------------------- */ void PairAIREBOOMP::FLJ_thr(int ifrom, int ito, int evflag, int eflag, int vflag_atom, double *pv1, ThrData * const thr) { int i,j,k,m,ii,jj,kk,mm,jnum,itype,jtype,ktype,mtype; tagint itag,jtag; int atomi,atomj,atomk,atomm; int testpath,npath,done; 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; const double * const * const x = atom->x; double * const * const f = thr->get_f(); tagint *tag = atom->tag; int *type = atom->type; int nlocal = atom->nlocal; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; // loop over neighbors of my atoms for (ii = ifrom; ii < ito; 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) / 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_thr(i,j,delscale,rcmin[itype][jtype],VA, delij,rij,vflag_atom,thr); } 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) *pv1 += evdwl = VA*Stb + (1.0-Str)*cij*VLJ; if (evflag) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1, evdwl,0.0,fpair,delij[0],delij[1],delij[2],thr); 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_thr(atomi,atomj,fpair,delij,thr); } 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_thr(atomi,atomj,atomk,fi,fj,delikS,deljkS,thr); } 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_thr(atomi,atomj,atomk,atomm,fi,fj,fk,delimS,deljmS,delkmS,thr); } } } } } } /* ---------------------------------------------------------------------- torsional forces and energy ------------------------------------------------------------------------- */ void PairAIREBOOMP::TORSION_thr(int ifrom, int ito, int evflag, int eflag, double *pv2, ThrData * const thr) { int i,j,k,l,ii; 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; const double * const * const x = atom->x; double * const * const f = thr->get_f(); int *type = atom->type; tagint *tag = atom->tag; ilist = list->ilist; for (ii = ifrom; ii < ito; 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) *pv2 += 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_thr(this,i,j,k,l,evdwl,fi,fj,fk,delil,del34,delkl,thr); } } } } } } /* ---------------------------------------------------------------------- Bij function ------------------------------------------------------------------------- */ double PairAIREBOOMP::bondorder_thr(int i, int j, double rij[3], double rijmag, double VA, int vflag_atom, ThrData * const thr) { 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 dt2dik[3],dt2djl[3],dt2dij[3],aa,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; const double * const * const x = atom->x; double * const * const f = thr->get_f(); 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 = 1.0/sqrt(1.0+Etmp+PijS); tmp = -0.5*pij*pij*pij; const double invrijm = 1.0/rijmag; const double invrijm2 = invrijm*invrijm; // 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); const double invrikm = 1.0/rikmag; const double invrijkm = invrijm*invrikm; const double invrikm2 = invrikm*invrikm; cosjik = (rij[0]*rik[0] + rij[1]*rik[1] + rij[2]*rik[2]) * invrijkm; cosjik = MIN(cosjik,1.0); cosjik = MAX(cosjik,-1.0); dcosjikdri[0] = ((rij[0]+rik[0])*invrijkm) - (cosjik*((rij[0]*invrijm2)+(rik[0]*invrikm2))); dcosjikdri[1] = ((rij[1]+rik[1])*invrijkm) - (cosjik*((rij[1]*invrijm2)+(rik[1]*invrikm2))); dcosjikdri[2] = ((rij[2]+rik[2])*invrijkm) - (cosjik*((rij[2]*invrijm2)+(rik[2]*invrikm2))); dcosjikdrk[0] = (-rij[0]*invrijkm) + (cosjik*(rik[0]*invrikm2)); dcosjikdrk[1] = (-rij[1]*invrijkm) + (cosjik*(rik[1]*invrikm2)); dcosjikdrk[2] = (-rij[2]*invrijkm) + (cosjik*(rik[2]*invrikm2)); dcosjikdrj[0] = (-rik[0]*invrijkm) + (cosjik*(rij[0]*invrijm2)); dcosjikdrj[1] = (-rik[1]*invrijkm) + (cosjik*(rij[1]*invrijm2)); dcosjikdrj[2] = (-rik[2]*invrijkm) + (cosjik*(rij[2]*invrijm2)); 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]*invrijm); fj[1] -= tmp2*(-rij[1]*invrijm); fj[2] -= tmp2*(-rij[2]*invrijm); fi[0] -= tmp2*((-rik[0]*invrikm)+(rij[0]*invrijm)); fi[1] -= tmp2*((-rik[1]*invrikm)+(rij[1]*invrijm)); fi[2] -= tmp2*((-rik[2]*invrikm)+(rij[2]*invrijm)); fk[0] -= tmp2*(rik[0]*invrikm); fk[1] -= tmp2*(rik[1]*invrikm); fk[2] -= tmp2*(rik[2]*invrikm); // coordination forces // dwik forces tmp2 = VA*.5*(tmp*dwik*g*exp(lamdajik))*invrikm; 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)*invrikm; 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)*invrikm; 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_thr(atomi,atomj,atomk,fj,fk,rji,rki,thr); } } } 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 = 1.0/sqrt(1.0+Etmp+PjiS); tmp = -0.5*pji*pji*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); const double invrjlm = 1.0/rjlmag; const double invrijlm = invrijm*invrjlm; const double invrjlm2 = invrjlm*invrjlm; cosijl = (-1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2]))) * invrijlm; cosijl = MIN(cosijl,1.0); cosijl = MAX(cosijl,-1.0); dcosijldri[0] = (-rjl[0]*invrijlm) - (cosijl*rij[0]*invrijm2); dcosijldri[1] = (-rjl[1]*invrijlm) - (cosijl*rij[1]*invrijm2); dcosijldri[2] = (-rjl[2]*invrijlm) - (cosijl*rij[2]*invrijm2); dcosijldrj[0] = ((-rij[0]+rjl[0])*invrijlm) + (cosijl*((rij[0]*invrijm2)-(rjl[0]*invrjlm2))); dcosijldrj[1] = ((-rij[1]+rjl[1])*invrijlm) + (cosijl*((rij[1]*invrijm2)-(rjl[1]*invrjlm2))); dcosijldrj[2] = ((-rij[2]+rjl[2])*invrijlm) + (cosijl*((rij[2]*invrijm2)-(rjl[2]*invrjlm2))); dcosijldrl[0] = (rij[0]*invrijlm)+(cosijl*rjl[0]*invrjlm2); dcosijldrl[1] = (rij[1]*invrijlm)+(cosijl*rjl[1]*invrjlm2); dcosijldrl[2] = (rij[2]*invrijlm)+(cosijl*rjl[2]*invrjlm2); // 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]*invrijm); fi[1] -= tmp2*(rij[1]*invrijm); fi[2] -= tmp2*(rij[2]*invrijm); fj[0] -= tmp2*((-rjl[0]*invrjlm)-(rij[0]*invrijm)); fj[1] -= tmp2*((-rjl[1]*invrjlm)-(rij[1]*invrijm)); fj[2] -= tmp2*((-rjl[2]*invrjlm)-(rij[2]*invrijm)); fl[0] -= tmp2*(rjl[0]*invrjlm); fl[1] -= tmp2*(rjl[1]*invrjlm); fl[2] -= tmp2*(rjl[2]*invrjlm); // coordination forces // dwik forces tmp2 = VA*.5*(tmp*dwjl*g*exp(lamdaijl))*invrjlm; 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)*invrjlm; 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)*invrjlm; 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_thr(atomi,atomj,atoml,fi,fl,rij,rlj,thr); } } } // 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_thr(atomi,atomk,-tmp2,rik,thr); // due to kronecker(ktype, 0) term in contribution // to NconjtmpI and later Nijconj if (ktype != 0) continue; 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_thr(atomi,atomk,-tmp2,rik,thr); 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_thr(atomk,atomn,-tmp2,rkn,thr); } } } } } // 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_thr(atomj,atoml,-tmp2,rjl,thr); // due to kronecker(ltype, 0) term in contribution // to NconjtmpJ and later Nijconj if (ltype != 0) continue; 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_thr(atomj,atoml,-tmp2,rjl,thr); 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_thr(atoml,atomn,-tmp2,rln,thr); } } } } } 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 = -prefactor*(1.0-square(om1234)) * 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_thr(atom1,atom2,atom3,atom4,f1,f2,f4,r13,r23,r43,thr); } } } } } } } // 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_thr(atomi,atomk,-tmp2,rik,thr); // due to kronecker(ktype, 0) term in contribution // to NconjtmpI and later Nijconj if (ktype != 0) continue; 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_thr(atomi,atomk,-tmp2,rik,thr); 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_thr(atomk,atomn,-tmp2,rkn,thr); } } } } } // 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_thr(atomj,atoml,-tmp2,rjl,thr); // due to kronecker(ltype, 0) term in contribution // to NconjtmpJ and later Nijconj if (ltype != 0) continue; 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_thr(atomj,atoml,-tmp2,rjl,thr); 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_thr(atoml,atomn,-tmp2,rln,thr); } } } } } } bij = (0.5*(pij+pji))+piRC+(Tij*Etmp); return bij; } /* ---------------------------------------------------------------------- Bij* function ------------------------------------------------------------------------- */ double PairAIREBOOMP::bondorderLJ_thr(int i, int j, double rij[3], double rijmag, double VA, double rij0[3], double rij0mag, int vflag_atom, ThrData * const thr) { 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 dN2[2],dN3[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 fcikpc,fcjlpc,fcjkpc,fcilpc; - double dt2dik[3],dt2djl[3],aa,aaa1,aaa2,at2,cw,cwnum,cwnom; + double dt2dik[3],dt2djl[3],aa,aaa2,at2,cw,cwnum,cwnom; double sin321,sin234,rr,rijrik,rijrjl,rjk2,rik2,ril2,rjl2; double dctik,dctjk,dctjl,dctil,rik2i,rjl2i,sink2i,sinl2i; double rjk[3],ril[3],dt1dik,dt1djk,dt1djl,dt1dil; 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],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 realrij[3], realrijmag; double rjkmag, rilmag, dctdjk, dctdik, dctdil, dctdjl; double fjk[3], fil[3], rijmbr; const double * const * const x = atom->x; double * const * const f = thr->get_f(); const int * const 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; realrij[0] = x[atomi][0] - x[atomj][0]; realrij[1] = x[atomi][1] - x[atomj][1]; realrij[2] = x[atomi][2] - x[atomj][2]; realrijmag = sqrt(realrij[0] * realrij[0] + realrij[1] * realrij[1] + realrij[2] * realrij[2]); 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 = 1.0/sqrt(1.0+Etmp+PijS); tmppij = -.5*pij*pij*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 = 1.0/sqrt(1.0+Etmp+PjiS); tmppji = -.5*pji*pji*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); rjk[0] = rik[0] - rij[0]; rjk[1] = rik[1] - rij[1]; rjk[2] = rik[2] - rij[2]; rjkmag = sqrt(rjk[0] * rjk[0] + rjk[1] * rjk[1] + rjk[2] * rjk[2]); rijrik = 2 * rijmag * rikmag; rr = rijmag * rijmag - rikmag * rikmag; cosjik = (rijmag * rijmag + rikmag * rikmag - rjkmag * rjkmag) / rijrik; cosjik = MIN(cosjik,1.0); cosjik = MAX(cosjik,-1.0); dctdjk = -2 / rijrik; dctdik = (-rr + rjkmag * rjkmag) / (rijrik * rikmag * rikmag); // evaluate splines g and derivatives dg g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN); tmp2 = VA*.5*(tmp*wik*dgdc*exp(lamdajik)); fi[0] = -tmp2 * dctdik * rik[0]; fi[1] = -tmp2 * dctdik * rik[1]; fi[2] = -tmp2 * dctdik * rik[2]; fk[0] = tmp2 * dctdik * rik[0]; fk[1] = tmp2 * dctdik * rik[1]; fk[2] = tmp2 * dctdik * rik[2]; fj[0] = 0; fj[1] = 0; fj[2] = 0; fjk[0] = -tmp2 * dctdjk * rjk[0]; fjk[1] = -tmp2 * dctdjk * rjk[1]; fjk[2] = -tmp2 * dctdjk * rjk[2]; fi[0] += fjk[0]; fi[1] += fjk[1]; fi[2] += fjk[2]; fk[0] -= fjk[0]; fk[1] -= fjk[1]; fk[2] -= fjk[2]; rijmbr = rcmin[itype][jtype] / realrijmag; fj[0] += rijmbr * (fjk[0] - (realrij[0] * realrij[0] * fjk[0] + realrij[0] * realrij[1] * fjk[1] + realrij[0] * realrij[2] * fjk[2]) / (realrijmag * realrijmag)); fj[1] += rijmbr * (fjk[1] - (realrij[1] * realrij[0] * fjk[0] + realrij[1] * realrij[1] * fjk[1] + realrij[1] * realrij[2] * fjk[2]) / (realrijmag * realrijmag)); fj[2] += rijmbr * (fjk[2] - (realrij[2] * realrij[0] * fjk[0] + realrij[2] * realrij[1] * fjk[1] + realrij[2] * realrij[2] * fjk[2]) / (realrijmag * realrijmag)); fi[0] -= rijmbr * (fjk[0] - (realrij[0] * realrij[0] * fjk[0] + realrij[0] * realrij[1] * fjk[1] + realrij[0] * realrij[2] * fjk[2]) / (realrijmag * realrijmag)); fi[1] -= rijmbr * (fjk[1] - (realrij[1] * realrij[0] * fjk[0] + realrij[1] * realrij[1] * fjk[1] + realrij[1] * realrij[2] * fjk[2]) / (realrijmag * realrijmag)); fi[2] -= rijmbr * (fjk[2] - (realrij[2] * realrij[0] * fjk[0] + realrij[2] * realrij[1] * fjk[1] + realrij[2] * realrij[2] * fjk[2]) / (realrijmag * realrijmag)); tmp2 = VA*.5*(tmp*wik*g*exp(lamdajik)*4.0*kronecker(itype,1)); fi[0] += tmp2*(rik[0]/rikmag); fi[1] += tmp2*(rik[1]/rikmag); fi[2] += tmp2*(rik[2]/rikmag); 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_thr(atomi,atomj,atomk,fj,fk,rji,rki,thr); } } } 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); ril[0] = rij[0] + rjl[0]; ril[1] = rij[1] + rjl[1]; ril[2] = rij[2] + rjl[2]; rilmag = sqrt(ril[0] * ril[0] + ril[1] * ril[1] + ril[2] * ril[2]); rijrjl = 2 * rijmag * rjlmag; rr = rijmag * rijmag - rjlmag * rjlmag; cosijl = (rijmag * rijmag + rjlmag * rjlmag - rilmag * rilmag) / rijrjl; cosijl = MIN(cosijl,1.0); cosijl = MAX(cosijl,-1.0); dctdil = -2 / rijrjl; dctdjl = (-rr + rilmag * rilmag) / (rijrjl * rjlmag * rjlmag); // evaluate splines g and derivatives dg g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN); tmp2 = VA*.5*(tmp*wjl*dgdc*exp(lamdaijl)); fj[0] = -tmp2 * dctdjl * rjl[0]; fj[1] = -tmp2 * dctdjl * rjl[1]; fj[2] = -tmp2 * dctdjl * rjl[2]; fl[0] = tmp2 * dctdjl * rjl[0]; fl[1] = tmp2 * dctdjl * rjl[1]; fl[2] = tmp2 * dctdjl * rjl[2]; fi[0] = 0; fi[1] = 0; fi[2] = 0; fil[0] = -tmp2 * dctdil * ril[0]; fil[1] = -tmp2 * dctdil * ril[1]; fil[2] = -tmp2 * dctdil * ril[2]; fj[0] += fil[0]; fj[1] += fil[1]; fj[2] += fil[2]; fl[0] -= fil[0]; fl[1] -= fil[1]; fl[2] -= fil[2]; rijmbr = rcmin[itype][jtype] / realrijmag; fi[0] += rijmbr * (fil[0] - (realrij[0] * realrij[0] * fil[0] + realrij[0] * realrij[1] * fil[1] + realrij[0] * realrij[2] * fil[2]) / (realrijmag * realrijmag)); fi[1] += rijmbr * (fil[1] - (realrij[1] * realrij[0] * fil[0] + realrij[1] * realrij[1] * fil[1] + realrij[1] * realrij[2] * fil[2]) / (realrijmag * realrijmag)); fi[2] += rijmbr * (fil[2] - (realrij[2] * realrij[0] * fil[0] + realrij[2] * realrij[1] * fil[1] + realrij[2] * realrij[2] * fil[2]) / (realrijmag * realrijmag)); fj[0] -= rijmbr * (fil[0] - (realrij[0] * realrij[0] * fil[0] + realrij[0] * realrij[1] * fil[1] + realrij[0] * realrij[2] * fil[2]) / (realrijmag * realrijmag)); fj[1] -= rijmbr * (fil[1] - (realrij[1] * realrij[0] * fil[0] + realrij[1] * realrij[1] * fil[1] + realrij[1] * realrij[2] * fil[2]) / (realrijmag * realrijmag)); fj[2] -= rijmbr * (fil[2] - (realrij[2] * realrij[0] * fil[0] + realrij[2] * realrij[1] * fil[1] + realrij[2] * realrij[2] * fil[2]) / (realrijmag * realrijmag)); tmp2 = VA*.5*(tmp*wjl*g*exp(lamdaijl)*4.0*kronecker(jtype,1)); fj[0] += tmp2*(rjl[0]/rjlmag); fj[1] += tmp2*(rjl[1]/rjlmag); fj[2] += tmp2*(rjl[2]/rjlmag); 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_thr(atomi,atomj,atoml,fi,fl,rij,rlj,thr); } } } // 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_thr(atomi,atomk,-tmp2,rik,thr); // due to kronecker(ktype, 0) term in contribution // to NconjtmpI and later Nijconj if (ktype != 0) continue; 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_thr(atomi,atomk,-tmp2,rik,thr); 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_thr(atomk,atomn,-tmp2,rkn,thr); } } } } } // 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_thr(atomj,atoml,-tmp2,rjl,thr); // due to kronecker(ltype, 0) term in contribution // to NconjtmpJ and later Nijconj if (ltype != 0) continue; 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_thr(atomj,atoml,-tmp2,rjl,thr); 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_thr(atoml,atomn,-tmp2,rln,thr); } } } } } if (fabs(Tij) > TOL) { dN3[0] = dN3Tij[0]; dN3[1] = dN3Tij[1]; dN3[2] = dN3Tij[2]; atom2 = atomi; atom3 = atomj; r32[0] = -rij[0]; r32[1] = -rij[1]; r32[2] = -rij[2]; r23[0] = rij[0]; r23[1] = rij[1]; r23[2] = rij[2]; r32mag = rijmag; r23mag = rijmag; 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); 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); 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; dt1dik = (rik2i)-(dctik*sink2i*cos321); dt1djk = (-dctjk*sink2i*cos321); dt1djl = (rjl2i)-(dctjl*sinl2i*cos234); dt1dil = (-dctil*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]); 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 = -prefactor*(1.0-square(om1234)) * w21*w34; at2 = aa*cwnum; 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)); 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] = F12[0]+F31[0]; f2[1] = F12[1]+F31[1]; f2[2] = F12[2]+F31[2]; f3[0] = F34[0]+F24[0]; f3[1] = F34[1]+F24[1]; f3[2] = F34[2]+F24[2]; f4[0] = -F34[0]-F24[0]; f4[1] = -F34[1]-F24[1]; f4[2] = -F34[2]-F24[2]; rijmbr = rcmin[itype][jtype] / realrijmag; f2[0] += rijmbr * (F24[0] - (realrij[0] * realrij[0] * F24[0] + realrij[0] * realrij[1] * F24[1] + realrij[0] * realrij[2] * F24[2]) / (realrijmag * realrijmag)); f2[1] += rijmbr * (F24[1] - (realrij[1] * realrij[0] * F24[0] + realrij[1] * realrij[1] * F24[1] + realrij[1] * realrij[2] * F24[2]) / (realrijmag * realrijmag)); f2[2] += rijmbr * (F24[2] - (realrij[2] * realrij[0] * F24[0] + realrij[2] * realrij[1] * F24[1] + realrij[2] * realrij[2] * F24[2]) / (realrijmag * realrijmag)); f3[0] -= rijmbr * (F24[0] - (realrij[0] * realrij[0] * F24[0] + realrij[0] * realrij[1] * F24[1] + realrij[0] * realrij[2] * F24[2]) / (realrijmag * realrijmag)); f3[1] -= rijmbr * (F24[1] - (realrij[1] * realrij[0] * F24[0] + realrij[1] * realrij[1] * F24[1] + realrij[1] * realrij[2] * F24[2]) / (realrijmag * realrijmag)); f3[2] -= rijmbr * (F24[2] - (realrij[2] * realrij[0] * F24[0] + realrij[2] * realrij[1] * F24[1] + realrij[2] * realrij[2] * F24[2]) / (realrijmag * realrijmag)); f2[0] -= rijmbr * (F31[0] - (realrij[0] * realrij[0] * F31[0] + realrij[0] * realrij[1] * F31[1] + realrij[0] * realrij[2] * F31[2]) / (realrijmag * realrijmag)); f2[1] -= rijmbr * (F31[1] - (realrij[1] * realrij[0] * F31[0] + realrij[1] * realrij[1] * F31[1] + realrij[1] * realrij[2] * F31[2]) / (realrijmag * realrijmag)); f2[2] -= rijmbr * (F31[2] - (realrij[2] * realrij[0] * F31[0] + realrij[2] * realrij[1] * F31[1] + realrij[2] * realrij[2] * F31[2]) / (realrijmag * realrijmag)); f3[0] += rijmbr * (F31[0] - (realrij[0] * realrij[0] * F31[0] + realrij[0] * realrij[1] * F31[1] + realrij[0] * realrij[2] * F31[2]) / (realrijmag * realrijmag)); f3[1] += rijmbr * (F31[1] - (realrij[1] * realrij[0] * F31[0] + realrij[1] * realrij[1] * F31[1] + realrij[1] * realrij[2] * F31[2]) / (realrijmag * realrijmag)); f3[2] += rijmbr * (F31[2] - (realrij[2] * realrij[0] * F31[0] + realrij[2] * realrij[1] * F31[1] + realrij[2] * realrij[2] * F31[2]) / (realrijmag * realrijmag)); // 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_thr(atom1,atom2,atom3,atom4,f1,f2,f4,r13,r23,r43,thr); } } } } } } } 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_thr(atomi,atomk,-tmp2,rik,thr); // due to kronecker(ktype, 0) term in contribution // to NconjtmpI and later Nijconj if (ktype != 0) continue; 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_thr(atomi,atomk,-tmp2,rik,thr); 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_thr(atomk,atomn,-tmp2,rkn,thr); } } } } } // 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_thr(atomj,atoml,-tmp2,rjl,thr); // due to kronecker(ltype, 0) term in contribution // to NconjtmpJ and later Nijconj if (ltype != 0) continue; 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_thr(atomj,atoml,-tmp2,rjl,thr); 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_thr(atoml,atomn,-tmp2,rln,thr); } } } } } } } return Stb; } /* ---------------------------------------------------------------------- */ double PairAIREBOOMP::memory_usage() { double bytes = memory_usage_thr(); bytes += PairAIREBO::memory_usage(); return bytes; } diff --git a/src/USER-OMP/pair_reaxc_omp.cpp b/src/USER-OMP/pair_reaxc_omp.cpp index 0fb24ed5f..91fa3d38c 100644 --- a/src/USER-OMP/pair_reaxc_omp.cpp +++ b/src/USER-OMP/pair_reaxc_omp.cpp @@ -1,603 +1,604 @@ /* ---------------------------------------------------------------------- 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: Hasan Metin Aktulga, Purdue University (now at Lawrence Berkeley National Laboratory, hmaktulga@lbl.gov) Per-atom energy/virial added by Ray Shan (Sandia) Fix reax/c/bonds and fix reax/c/species for pair_style reax/c added by Ray Shan (Sandia) ------------------------------------------------------------------------- */ #include "pair_reaxc_omp.h" #include "atom.h" #include "update.h" #include "force.h" #include "comm.h" #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" #include "modify.h" #include "fix.h" #include "fix_reaxc.h" #include "citeme.h" #include "memory.h" #include "error.h" #include "timer.h" #include "reaxc_types.h" #include "reaxc_allocate.h" #include "reaxc_control.h" #include "reaxc_ffield.h" #include "reaxc_forces_omp.h" #include "reaxc_init_md_omp.h" #include "reaxc_io_tools.h" #include "reaxc_list.h" #include "reaxc_lookup.h" #include "reaxc_reset_tools.h" #include "reaxc_tool_box.h" #include "reaxc_traj.h" #include "reaxc_vector.h" #include "fix_reaxc_bonds.h" #if defined(_OPENMP) #include #endif using namespace LAMMPS_NS; #ifdef OMP_TIMING double ompTimingData[LASTTIMINGINDEX]; int ompTimingCount[LASTTIMINGINDEX]; int ompTimingCGCount[LASTTIMINGINDEX]; #endif /* ---------------------------------------------------------------------- */ PairReaxCOMP::PairReaxCOMP(LAMMPS *lmp) : PairReaxC(lmp), ThrOMP(lmp, THR_PAIR) { suffix_flag |= Suffix::OMP; system->pair_ptr = this; num_nbrs_offset = NULL; #ifdef OMP_TIMING for (int i=0;inum_intrs; ++i) sfree(bonds->select.bond_list[i].bo_data.CdboReduction, "CdboReduction"); memory->destroy(num_nbrs_offset); #ifdef OMP_TIMING int myrank; MPI_Comm_rank(mpi_data->world,&myrank); // Write screen output if (timer->has_full() && myrank == 0 && screen) { fprintf(screen,"\n\nWrite_Lists took %11.3lf seconds", ompTimingData[COMPUTEWLINDEX]); fprintf(screen,"\n\nCompute_Forces took %11.3lf seconds:", ompTimingData[COMPUTEINDEX]); fprintf(screen,"\n ->Initial Forces: %11.3lf seconds", ompTimingData[COMPUTEIFINDEX]); fprintf(screen,"\n ->Bond Order: %11.3lf seconds", ompTimingData[COMPUTEBOINDEX]); fprintf(screen,"\n ->Atom Energy: %11.3lf seconds", ompTimingData[COMPUTEATOMENERGYINDEX]); fprintf(screen,"\n ->Bond: %11.3lf seconds", ompTimingData[COMPUTEBONDSINDEX]); fprintf(screen,"\n ->Hydrogen bonds: %11.3lf seconds", ompTimingData[COMPUTEHBONDSINDEX]); fprintf(screen,"\n ->Torsion Angles: %11.3lf seconds", ompTimingData[COMPUTETORSIONANGLESBOINDEX]); fprintf(screen,"\n ->Valence Angles: %11.3lf seconds", ompTimingData[COMPUTEVALENCEANGLESBOINDEX]); fprintf(screen,"\n ->Non-Bonded For: %11.3lf seconds", ompTimingData[COMPUTENBFINDEX]); fprintf(screen,"\n ->Total Forces: %11.3lf seconds", ompTimingData[COMPUTETFINDEX]); fprintf(screen,"\n\nfixQEQ: %11.3lf seconds", ompTimingData[COMPUTEQEQINDEX]); fprintf(screen,"\n ->QEQ init: %11.3lf seconds", ompTimingData[COMPUTEINITMVINDEX]); double avg = double(ompTimingCGCount[COMPUTECG1INDEX]) / double(ompTimingCount[COMPUTECG1INDEX]); fprintf(screen,"\n ->QEQ CG1: %11.3lf seconds with %4.1lf iterations on average.", ompTimingData[COMPUTECG1INDEX], avg); avg = double(ompTimingCGCount[COMPUTECG2INDEX]) / double(ompTimingCount[COMPUTECG2INDEX]); fprintf(screen,"\n ->QEQ CG2: %11.3lf seconds with %4.1lf iterations on average.", ompTimingData[COMPUTECG2INDEX], avg); fprintf(screen,"\n ->QEQ CalcQ: %11.3lf seconds\n", ompTimingData[COMPUTECALCQINDEX]); } // Write logfile output if (timer->has_full() && myrank == 0 && logfile) { fprintf(logfile,"\n\nWrite_Lists took %11.3lf seconds", ompTimingData[COMPUTEWLINDEX]); fprintf(logfile,"\n\nCompute_Forces took %11.3lf seconds:", ompTimingData[COMPUTEINDEX]); fprintf(logfile,"\n ->Initial Forces: %11.3lf seconds", ompTimingData[COMPUTEIFINDEX]); fprintf(logfile,"\n ->Bond Order: %11.3lf seconds", ompTimingData[COMPUTEBOINDEX]); fprintf(logfile,"\n ->Atom Energy: %11.3lf seconds", ompTimingData[COMPUTEATOMENERGYINDEX]); fprintf(logfile,"\n ->Bond: %11.3lf seconds", ompTimingData[COMPUTEBONDSINDEX]); fprintf(logfile,"\n ->Hydrogen bonds: %11.3lf seconds", ompTimingData[COMPUTEHBONDSINDEX]); fprintf(logfile,"\n ->Torsion Angles: %11.3lf seconds", ompTimingData[COMPUTETORSIONANGLESBOINDEX]); fprintf(logfile,"\n ->Valence Angles: %11.3lf seconds", ompTimingData[COMPUTEVALENCEANGLESBOINDEX]); fprintf(logfile,"\n ->Non-Bonded For: %11.3lf seconds", ompTimingData[COMPUTENBFINDEX]); fprintf(logfile,"\n ->Total Forces: %11.3lf seconds", ompTimingData[COMPUTETFINDEX]); fprintf(logfile,"\n\nfixQEQ: %11.3lf seconds", ompTimingData[COMPUTEQEQINDEX]); fprintf(logfile,"\n ->QEQ init: %11.3lf seconds", ompTimingData[COMPUTEINITMVINDEX]); double avg = double(ompTimingCGCount[COMPUTECG1INDEX]) / double(ompTimingCount[COMPUTECG1INDEX]); fprintf(logfile,"\n ->QEQ CG1: %11.3lf seconds with %4.1lf iterations on average.", ompTimingData[COMPUTECG1INDEX], avg); avg = double(ompTimingCGCount[COMPUTECG2INDEX]) / double(ompTimingCount[COMPUTECG2INDEX]); fprintf(logfile,"\n ->QEQ CG2: %11.3lf seconds with %4.1lf iterations on average.", ompTimingData[COMPUTECG2INDEX], avg); fprintf(logfile,"\n ->QEQ CalcQ: %11.3lf seconds\n", ompTimingData[COMPUTECALCQINDEX]); } #endif } /* ---------------------------------------------------------------------- */ void PairReaxCOMP::compute(int eflag, int vflag) { double evdwl,ecoul; double t_start, t_end; // communicate num_bonds once every reneighboring // 2 num arrays stored by fix, grab ptr to them if (neighbor->ago == 0) comm->forward_comm_fix(fix_reax); int *num_bonds = fix_reax->num_bonds; int *num_hbonds = fix_reax->num_hbonds; evdwl = ecoul = 0.0; if (eflag || vflag) ev_setup(eflag,vflag); else ev_unset(); if (vflag_global) control->virial = 1; else control->virial = 0; system->n = atom->nlocal; // my atoms system->N = atom->nlocal + atom->nghost; // mine + ghosts system->bigN = static_cast (atom->natoms); // all atoms in the system system->big_box.V = 0; system->big_box.box_norms[0] = 0; system->big_box.box_norms[1] = 0; system->big_box.box_norms[2] = 0; if( comm->me == 0 ) t_start = MPI_Wtime(); // setup data structures setup(); Reset( system, control, data, workspace, &lists, world ); // Why not update workspace like in MPI-only code? // Using the MPI-only way messes up the hb energy //workspace->realloc.num_far = write_reax_lists(); write_reax_lists(); // timing for filling in the reax lists if( comm->me == 0 ) { t_end = MPI_Wtime(); data->timing.nbrs = t_end - t_start; } // forces #ifdef OMP_TIMING double startTimeBase,endTimeBase; startTimeBase = MPI_Wtime(); #endif Compute_ForcesOMP(system,control,data,workspace,&lists,out_control,mpi_data); read_reax_forces(vflag); #ifdef OMP_TIMING endTimeBase = MPI_Wtime(); ompTimingData[COMPUTEINDEX] += (endTimeBase-startTimeBase); #endif #if defined(_OPENMP) #pragma omp parallel for schedule(static) #endif for(int k = 0; k < system->N; ++k) { num_bonds[k] = system->my_atoms[k].num_bonds; num_hbonds[k] = system->my_atoms[k].num_hbonds; } // energies and pressure if (eflag_global) { evdwl += data->my_en.e_bond; evdwl += data->my_en.e_ov; evdwl += data->my_en.e_un; evdwl += data->my_en.e_lp; evdwl += data->my_en.e_ang; evdwl += data->my_en.e_pen; evdwl += data->my_en.e_coa; evdwl += data->my_en.e_hb; evdwl += data->my_en.e_tor; evdwl += data->my_en.e_con; evdwl += data->my_en.e_vdW; ecoul += data->my_en.e_ele; ecoul += data->my_en.e_pol; // Store the different parts of the energy // in a list for output by compute pair command pvector[0] = data->my_en.e_bond; pvector[1] = data->my_en.e_ov + data->my_en.e_un; pvector[2] = data->my_en.e_lp; pvector[3] = 0.0; pvector[4] = data->my_en.e_ang; pvector[5] = data->my_en.e_pen; pvector[6] = data->my_en.e_coa; pvector[7] = data->my_en.e_hb; pvector[8] = data->my_en.e_tor; pvector[9] = data->my_en.e_con; pvector[10] = data->my_en.e_vdW; pvector[11] = data->my_en.e_ele; pvector[12] = 0.0; pvector[13] = data->my_en.e_pol; } if (vflag_fdotr) virial_fdotr_compute(); // Set internal timestep counter to that of LAMMPS data->step = update->ntimestep; Output_Results( system, control, data, &lists, out_control, mpi_data ); // populate tmpid and tmpbo arrays for fix reax/c/species int i, j; if(fixspecies_flag) { if (system->N > nmax) { memory->destroy(tmpid); memory->destroy(tmpbo); nmax = system->N; memory->create(tmpid,nmax,MAXSPECBOND,"pair:tmpid"); memory->create(tmpbo,nmax,MAXSPECBOND,"pair:tmpbo"); } #if defined(_OPENMP) #pragma omp parallel for collapse(2) schedule(static) default(shared) #endif for (i = 0; i < system->N; i ++) for (j = 0; j < MAXSPECBOND; j ++) { tmpbo[i][j] = 0.0; tmpid[i][j] = 0; } FindBond(); } } /* ---------------------------------------------------------------------- */ void PairReaxCOMP::init_style( ) { if (!atom->q_flag) error->all(FLERR,"Pair reax/c/omp requires atom attribute q"); // firstwarn = 1; int iqeq = modify->find_fix_by_style("qeq/reax/omp"); if (iqeq < 0 && qeqflag == 1) error->all(FLERR,"Pair reax/c/omp requires use of fix qeq/reax/omp"); system->n = atom->nlocal; // my atoms system->N = atom->nlocal + atom->nghost; // mine + ghosts system->bigN = static_cast (atom->natoms); // all atoms in the system system->wsize = comm->nprocs; system->big_box.V = 0; system->big_box.box_norms[0] = 0; system->big_box.box_norms[1] = 0; system->big_box.box_norms[2] = 0; if (atom->tag_enable == 0) error->all(FLERR,"Pair style reax/c/omp requires atom IDs"); if (force->newton_pair == 0) error->all(FLERR,"Pair style reax/c/omp requires newton pair on"); // need a half neighbor list w/ Newton off and ghost neighbors // built whenever re-neighboring occurs int irequest = neighbor->request(this,instance_me); neighbor->requests[irequest]->newton = 2; neighbor->requests[irequest]->ghost = 1; cutmax = MAX3(control->nonb_cut, control->hbond_cut, 2*control->bond_cut); for( int i = 0; i < LIST_N; ++i ) lists[i].allocated = 0; if (fix_reax == NULL) { char **fixarg = new char*[3]; fixarg[0] = (char *) "REAXC"; fixarg[1] = (char *) "all"; fixarg[2] = (char *) "REAXC"; modify->add_fix(3,fixarg); delete [] fixarg; fix_reax = (FixReaxC *) modify->fix[modify->nfix-1]; } #if defined(_OPENMP) control->nthreads = omp_get_max_threads(); #else control->nthreads = 1; #endif } /* ---------------------------------------------------------------------- */ void PairReaxCOMP::setup( ) { int oldN; int mincap = system->mincap; double safezone = system->safezone; system->n = atom->nlocal; // my atoms system->N = atom->nlocal + atom->nghost; // mine + ghosts oldN = system->N; system->bigN = static_cast (atom->natoms); // all atoms in the system if (system->N > nmax) { memory->destroy(num_nbrs_offset); // Don't update nmax here. It is updated at end of compute(). memory->create(num_nbrs_offset, system->N, "pair:num_nbrs_offset"); } if (setup_flag == 0) { setup_flag = 1; int *num_bonds = fix_reax->num_bonds; int *num_hbonds = fix_reax->num_hbonds; control->vlist_cut = neighbor->cutneighmax; // determine the local and total capacity system->local_cap = MAX( (int)(system->n * safezone), mincap ); system->total_cap = MAX( (int)(system->N * safezone), mincap ); // initialize my data structures PreAllocate_Space( system, control, workspace, world ); write_reax_atoms(); int num_nbrs = estimate_reax_lists(); if(!Make_List(system->total_cap, num_nbrs, TYP_FAR_NEIGHBOR, lists+FAR_NBRS, world)) error->all(FLERR,"Pair reax/c problem in far neighbor list"); write_reax_lists(); InitializeOMP( system, control, data, workspace, &lists, out_control, mpi_data, world ); for( int k = 0; k < system->N; ++k ) { num_bonds[k] = system->my_atoms[k].num_bonds; num_hbonds[k] = system->my_atoms[k].num_hbonds; } } else { // fill in reax datastructures write_reax_atoms(); // reset the bond list info for new atoms for(int k = oldN; k < system->N; ++k) Set_End_Index( k, Start_Index( k, lists+BONDS ), lists+BONDS ); // estimate far neighbor list size // Not present in MPI-only version workspace->realloc.num_far = estimate_reax_lists(); // check if I need to shrink/extend my data-structs ReAllocate( system, control, data, workspace, &lists, mpi_data ); } } /* ---------------------------------------------------------------------- */ void PairReaxCOMP::write_reax_atoms() { int *num_bonds = fix_reax->num_bonds; int *num_hbonds = fix_reax->num_hbonds; if (system->N > system->total_cap) error->all(FLERR,"Too many ghost atoms"); #if defined(_OPENMP) #pragma omp parallel for schedule(static) default(shared) #endif for( int i = 0; i < system->N; ++i ){ system->my_atoms[i].orig_id = atom->tag[i]; system->my_atoms[i].type = map[atom->type[i]]; system->my_atoms[i].x[0] = atom->x[i][0]; system->my_atoms[i].x[1] = atom->x[i][1]; system->my_atoms[i].x[2] = atom->x[i][2]; system->my_atoms[i].q = atom->q[i]; system->my_atoms[i].num_bonds = num_bonds[i]; system->my_atoms[i].num_hbonds = num_hbonds[i]; } } /* ---------------------------------------------------------------------- */ int PairReaxCOMP::estimate_reax_lists() { int i; int *ilist = list->ilist; int *numneigh = list->numneigh; int numall = list->inum + list->gnum; int mincap = system->mincap; // for good performance in the OpenMP implementation, each thread needs // to know where to place the neighbors of the atoms it is responsible for. // The sumscan values for the list->numneigh will be used to determine the // neighbor offset of each atom. Note that this may cause some significant // memory overhead if delayed neighboring is used - so it may be desirable // to work on this part to reduce the memory footprint of the far_nbrs list. int num_nbrs = 0; for (int itr_i = 0; itr_i < numall; ++itr_i) { i = ilist[itr_i]; num_nbrs += numneigh[i]; } int new_estimate = MAX (num_nbrs, mincap*MIN_NBRS); return new_estimate; } /* ---------------------------------------------------------------------- */ int PairReaxCOMP::write_reax_lists() { #ifdef OMP_TIMING double startTimeBase, endTimeBase; startTimeBase = MPI_Wtime(); #endif int itr_i, itr_j, i, j, num_mynbrs; int *jlist; double d_sqr, dist, cutoff_sqr; rvec dvec; double **x = atom->x; int *ilist = list->ilist; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; reax_list *far_nbrs = lists + FAR_NBRS; far_neighbor_data *far_list = far_nbrs->select.far_nbr_list; int num_nbrs = 0; int inum = list->inum; int gnum = list->gnum; int numall = inum + gnum; // sumscan of the number of neighbors per atom to determine the offsets // most likely, we are overallocating. desirable to work on this part // to reduce the memory footprint of the far_nbrs list. num_nbrs = 0; for (itr_i = 0; itr_i < numall; ++itr_i) { i = ilist[itr_i]; num_nbrs_offset[i] = num_nbrs; num_nbrs += numneigh[i]; } #if defined(_OPENMP) #pragma omp parallel for schedule(dynamic,50) default(shared) \ private(itr_i, itr_j, i, j, jlist, cutoff_sqr, num_mynbrs, d_sqr, dvec, dist) #endif for (itr_i = 0; itr_i < numall; ++itr_i) { i = ilist[itr_i]; jlist = firstneigh[i]; Set_Start_Index( i, num_nbrs_offset[i], far_nbrs ); if (i < inum) cutoff_sqr = control->nonb_cut*control->nonb_cut; else cutoff_sqr = control->bond_cut*control->bond_cut; num_mynbrs = 0; for (itr_j = 0; itr_j < numneigh[i]; ++itr_j) { j = jlist[itr_j]; j &= NEIGHMASK; get_distance( x[j], x[i], &d_sqr, &dvec ); if (d_sqr <= cutoff_sqr) { dist = sqrt( d_sqr ); set_far_nbr( &far_list[num_nbrs_offset[i] + num_mynbrs], j, dist, dvec ); ++num_mynbrs; } } Set_End_Index( i, num_nbrs_offset[i] + num_mynbrs, far_nbrs ); } #ifdef OMP_TIMING endTimeBase = MPI_Wtime(); ompTimingData[COMPUTEWLINDEX] += (endTimeBase-startTimeBase); #endif return num_nbrs; } /* ---------------------------------------------------------------------- */ void PairReaxCOMP::read_reax_forces(int vflag) { #if defined(_OPENMP) #pragma omp parallel for schedule(static) default(shared) #endif for( int i = 0; i < system->N; ++i ) { system->my_atoms[i].f[0] = workspace->f[i][0]; system->my_atoms[i].f[1] = workspace->f[i][1]; system->my_atoms[i].f[2] = workspace->f[i][2]; atom->f[i][0] = -workspace->f[i][0]; atom->f[i][1] = -workspace->f[i][1]; atom->f[i][2] = -workspace->f[i][2]; } } /* ---------------------------------------------------------------------- */ void PairReaxCOMP::FindBond() { - int i, ii, j, pj, jtag, nj, jtmp, jj; - double bo_tmp, bo_cut, rij, rsq; - - bond_data *bo_ij; - bo_cut = 0.10; + const double bo_cut = 0.10; + int i; #if defined(_OPENMP) #pragma omp parallel for schedule(static) default(shared) \ - private(i, nj, pj, bo_ij, j, bo_tmp) + private(i) #endif for (i = 0; i < system->n; i++) { + int j, pj, nj; + double bo_tmp; + bond_data *bo_ij; + nj = 0; for( pj = Start_Index(i, lists); pj < End_Index(i, lists); ++pj ) { bo_ij = &( lists->select.bond_list[pj] ); j = bo_ij->nbr; if (j < i) continue; bo_tmp = bo_ij->bo_data.BO; if (bo_tmp >= bo_cut ) { tmpid[i][nj] = j; tmpbo[i][nj] = bo_tmp; nj ++; if (nj > MAXSPECBOND) error->all(FLERR,"Increase MAXSPECBOND in fix_reaxc_species.h"); } } } } diff --git a/src/USER-OMP/pair_reaxc_omp.h b/src/USER-OMP/pair_reaxc_omp.h index a5e077c30..156627ece 100644 --- a/src/USER-OMP/pair_reaxc_omp.h +++ b/src/USER-OMP/pair_reaxc_omp.h @@ -1,113 +1,113 @@ -/* ---------------------------------------------------------------------- +/* -*- 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: Hasan Metin Aktulga, Purdue University (now at Lawrence Berkeley National Laboratory, hmaktulga@lbl.gov) Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and Algorithmic Techniques", Parallel Computing, in press. ------------------------------------------------------------------------- */ #ifdef PAIR_CLASS PairStyle(reax/c/omp,PairReaxCOMP) #else #ifndef LMP_PAIR_REAXC_OMP_H #define LMP_PAIR_REAXC_OMP_H #include "pair_reaxc.h" #include "thr_omp.h" #include "suffix.h" namespace LAMMPS_NS { class PairReaxCOMP : public PairReaxC, public ThrOMP { public: PairReaxCOMP(class LAMMPS *); ~PairReaxCOMP(); virtual void compute(int, int); virtual void init_style(); inline FixOMP *getFixOMP() { return fix; }; inline void ev_setup_thr_proxy(int eflagparm, int vflagparm, int nallparm, double *eatomparm, double **vatomparm, ThrData *thrparm) { ev_setup_thr(eflagparm, vflagparm, nallparm, eatomparm, vatomparm, thrparm); }; // reduce per thread data as needed inline void reduce_thr_proxy(void * const styleparm, const int eflagparm, const int vflagparm, ThrData * const thrparm) { reduce_thr(styleparm, eflagparm, vflagparm, thrparm); } inline void ev_tally_thr_proxy(Pair * const pairparm, const int iparm, const int jparm, const int nlocalparm, const int newton_pairparm, const double evdwlparm, const double ecoulparm, const double fpairparm, const double delxparm, const double delyparm, const double delzparm, ThrData * const thrparm) { ev_tally_thr(pairparm, iparm, jparm, nlocalparm, newton_pairparm, evdwlparm, ecoulparm, fpairparm, delxparm, delyparm, delzparm, thrparm); } inline void ev_tally_xyz_thr_proxy(Pair * const pairparm, const int iparm, const int jparm, const int nlocalparm, const int newton_pairparm, const double evdwlparm, const double ecoulparm, const double fxparm, const double fyparm, const double fzparm, const double delxparm, const double delyparm, const double delzparm, ThrData * const thrparm) { ev_tally_xyz_thr(pairparm, iparm, jparm, nlocalparm, newton_pairparm, evdwlparm, ecoulparm, fxparm, fyparm, fzparm, delxparm, delyparm, delzparm, thrparm); } inline void ev_tally3_thr_proxy(Pair * const pairparm,int i, int j, int k, double evdwl, double ecoul, double *fj, double *fk, double *drji, double *drki, ThrData * const thrparm) { ev_tally3_thr(pairparm, i, j, k, evdwl, ecoul, fj, fk, drji, drki, thrparm); } protected: virtual void setup(); virtual void write_reax_atoms(); virtual int estimate_reax_lists(); virtual int write_reax_lists(); virtual void read_reax_forces(int); virtual void FindBond(); // work array used in write_reax_lists() int * num_nbrs_offset; }; } #endif #endif /* ERROR/WARNING messages: E: Too many ghost atoms Number of ghost atoms has increased too much during simulation and has exceeded the size of reax/c arrays. Increase safe_zone and min_cap in pair_style reax/c command */ diff --git a/src/USER-OMP/reaxc_bond_orders_omp.cpp b/src/USER-OMP/reaxc_bond_orders_omp.cpp index 222c00980..85755a39a 100644 --- a/src/USER-OMP/reaxc_bond_orders_omp.cpp +++ b/src/USER-OMP/reaxc_bond_orders_omp.cpp @@ -1,736 +1,724 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program Copyright (2010) Purdue University Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and Algorithmic Techniques", Parallel Computing, in press. 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 2 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: . ----------------------------------------------------------------------*/ #include "pair_reaxc_omp.h" #include "reaxc_types.h" #include "reaxc_bond_orders_omp.h" #include "reaxc_list.h" #include "reaxc_vector.h" #if defined(_OPENMP) #include #endif using namespace LAMMPS_NS; void Add_dBond_to_ForcesOMP( reax_system *system, int i, int pj, storage *workspace, reax_list **lists ) { reax_list *bonds = (*lists) + BONDS; bond_data *nbr_j, *nbr_k; bond_order_data *bo_ij, *bo_ji; dbond_coefficients coef; int pk, k, j; PairReaxCOMP *pair_reax_ptr = static_cast(system->pair_ptr); #if defined(_OPENMP) int tid = omp_get_thread_num(); #else int tid = 0; #endif ThrData *thr = pair_reax_ptr->getFixOMP()->get_thr(tid); long reductionOffset = (system->N * tid); /* Virial Tallying variables */ - double f_scaler; rvec fi_tmp, fj_tmp, fk_tmp, delij, delji, delki, delkj, temp; /* Initializations */ nbr_j = &(bonds->select.bond_list[pj]); j = nbr_j->nbr; bo_ij = &(nbr_j->bo_data); bo_ji = &(bonds->select.bond_list[ nbr_j->sym_index ].bo_data); double c = bo_ij->Cdbo + bo_ji->Cdbo; coef.C1dbo = bo_ij->C1dbo * c; coef.C2dbo = bo_ij->C2dbo * c; coef.C3dbo = bo_ij->C3dbo * c; c = bo_ij->Cdbopi + bo_ji->Cdbopi; coef.C1dbopi = bo_ij->C1dbopi * c; coef.C2dbopi = bo_ij->C2dbopi * c; coef.C3dbopi = bo_ij->C3dbopi * c; coef.C4dbopi = bo_ij->C4dbopi * c; c = bo_ij->Cdbopi2 + bo_ji->Cdbopi2; coef.C1dbopi2 = bo_ij->C1dbopi2 * c; coef.C2dbopi2 = bo_ij->C2dbopi2 * c; coef.C3dbopi2 = bo_ij->C3dbopi2 * c; coef.C4dbopi2 = bo_ij->C4dbopi2 * c; c = workspace->CdDelta[i] + workspace->CdDelta[j]; coef.C1dDelta = bo_ij->C1dbo * c; coef.C2dDelta = bo_ij->C2dbo * c; coef.C3dDelta = bo_ij->C3dbo * c; // The same "c" refactoring here can be replicated below in Add_dBond_to_Forces_NPTOMP(), but // I'd prefer to wait for a test to verify changes before doing so (just to be safe). // forces on i // rvec_Scale( temp, coef.C1dbo, bo_ij->dBOp ); // rvec_ScaledAdd( temp, coef.C2dbo, workspace->dDeltap_self[i] ); // rvec_ScaledAdd( temp, coef.C1dDelta, bo_ij->dBOp ); // rvec_ScaledAdd( temp, coef.C2dDelta, workspace->dDeltap_self[i] ); // rvec_ScaledAdd( temp, coef.C1dbopi, bo_ij->dln_BOp_pi ); // rvec_ScaledAdd( temp, coef.C2dbopi, bo_ij->dBOp ); // rvec_ScaledAdd( temp, coef.C3dbopi, workspace->dDeltap_self[i]); // rvec_ScaledAdd( temp, coef.C1dbopi2, bo_ij->dln_BOp_pi2 ); // rvec_ScaledAdd( temp, coef.C2dbopi2, bo_ij->dBOp ); // rvec_ScaledAdd( temp, coef.C3dbopi2, workspace->dDeltap_self[i] ); c = (coef.C1dbo + coef.C1dDelta + coef.C2dbopi + coef.C2dbopi2); rvec_Scale( temp, c, bo_ij->dBOp ); c = (coef.C2dbo + coef.C2dDelta + coef.C3dbopi + coef.C3dbopi2); rvec_ScaledAdd( temp, c, workspace->dDeltap_self[i] ); rvec_ScaledAdd( temp, coef.C1dbopi, bo_ij->dln_BOp_pi ); rvec_ScaledAdd( temp, coef.C1dbopi2, bo_ij->dln_BOp_pi2 ); rvec_Add(workspace->forceReduction[reductionOffset+i],temp ); if( system->pair_ptr->vflag_atom) { rvec_Scale(fi_tmp, -1.0, temp); rvec_ScaledSum( delij, 1., system->my_atoms[i].x,-1., system->my_atoms[j].x ); pair_reax_ptr->ev_tally_xyz_thr_proxy(system->pair_ptr,i,j,system->N,0,0,0, fi_tmp[0],fi_tmp[1],fi_tmp[2], delij[0],delij[1],delij[2],thr); } // forces on j // rvec_Scale( temp, -coef.C1dbo, bo_ij->dBOp ); // rvec_ScaledAdd( temp, coef.C3dbo, workspace->dDeltap_self[j] ); // rvec_ScaledAdd( temp, -coef.C1dDelta, bo_ij->dBOp ); // rvec_ScaledAdd( temp, coef.C3dDelta, workspace->dDeltap_self[j]); // rvec_ScaledAdd( temp, -coef.C1dbopi, bo_ij->dln_BOp_pi ); // rvec_ScaledAdd( temp, -coef.C2dbopi, bo_ij->dBOp ); // rvec_ScaledAdd( temp, coef.C4dbopi, workspace->dDeltap_self[j]); // rvec_ScaledAdd( temp, -coef.C1dbopi2, bo_ij->dln_BOp_pi2 ); // rvec_ScaledAdd( temp, -coef.C2dbopi2, bo_ij->dBOp ); // rvec_ScaledAdd( temp, coef.C4dbopi2, workspace->dDeltap_self[j]); c = -(coef.C1dbo + coef.C1dDelta + coef.C2dbopi + coef.C2dbopi2); rvec_Scale( temp, c, bo_ij->dBOp ); c = (coef.C3dbo + coef.C3dDelta + coef.C4dbopi + coef.C4dbopi2); rvec_ScaledAdd( temp, c, workspace->dDeltap_self[j] ); rvec_ScaledAdd( temp, -coef.C1dbopi, bo_ij->dln_BOp_pi ); rvec_ScaledAdd( temp, -coef.C1dbopi2, bo_ij->dln_BOp_pi2 ); rvec_Add(workspace->forceReduction[reductionOffset+j],temp ); if( system->pair_ptr->vflag_atom) { rvec_Scale(fj_tmp, -1.0, temp); rvec_ScaledSum( delji, 1., system->my_atoms[j].x,-1., system->my_atoms[i].x ); pair_reax_ptr->ev_tally_xyz_thr_proxy(system->pair_ptr,j,i,system->N,0,0,0, fj_tmp[0],fj_tmp[1],fj_tmp[2], delji[0],delji[1],delji[2],thr); } // forces on k: i neighbor for( pk = Start_Index(i, bonds); pk < End_Index(i, bonds); ++pk ) { nbr_k = &(bonds->select.bond_list[pk]); k = nbr_k->nbr; // rvec_Scale( temp, -coef.C2dbo, nbr_k->bo_data.dBOp); // rvec_ScaledAdd( temp, -coef.C2dDelta, nbr_k->bo_data.dBOp); // rvec_ScaledAdd( temp, -coef.C3dbopi, nbr_k->bo_data.dBOp); // rvec_ScaledAdd( temp, -coef.C3dbopi2, nbr_k->bo_data.dBOp); const double c = -(coef.C2dbo + coef.C2dDelta + coef.C3dbopi + coef.C3dbopi2); rvec_Scale(temp, c, nbr_k->bo_data.dBOp); rvec_Add(workspace->forceReduction[reductionOffset+k],temp ); if( system->pair_ptr->vflag_atom ) { rvec_Scale(fk_tmp, -1.0, temp); rvec_ScaledSum(delki,1.,system->my_atoms[k].x,-1.,system->my_atoms[i].x); pair_reax_ptr->ev_tally_xyz_thr_proxy(system->pair_ptr,k,i,system->N,0,0,0, fk_tmp[0],fk_tmp[1],fk_tmp[2], delki[0],delki[1],delki[2],thr); rvec_ScaledSum(delkj,1.,system->my_atoms[k].x,-1.,system->my_atoms[j].x); pair_reax_ptr->ev_tally_xyz_thr_proxy(system->pair_ptr,k,j,system->N,0,0,0, fk_tmp[0],fk_tmp[1],fk_tmp[2], delkj[0],delkj[1],delkj[2],thr); } } // forces on k: j neighbor for( pk = Start_Index(j, bonds); pk < End_Index(j, bonds); ++pk ) { nbr_k = &(bonds->select.bond_list[pk]); k = nbr_k->nbr; // rvec_Scale( temp, -coef.C3dbo, nbr_k->bo_data.dBOp ); // rvec_ScaledAdd( temp, -coef.C3dDelta, nbr_k->bo_data.dBOp); // rvec_ScaledAdd( temp, -coef.C4dbopi, nbr_k->bo_data.dBOp); // rvec_ScaledAdd( temp, -coef.C4dbopi2, nbr_k->bo_data.dBOp); const double c = -(coef.C3dbo + coef.C3dDelta + coef.C4dbopi + coef.C4dbopi2); rvec_Scale(temp, c, nbr_k->bo_data.dBOp); rvec_Add(workspace->forceReduction[reductionOffset+k],temp ); if( system->pair_ptr->vflag_atom ) { rvec_Scale(fk_tmp, -1.0, temp); rvec_ScaledSum(delki,1.,system->my_atoms[k].x,-1.,system->my_atoms[i].x); pair_reax_ptr->ev_tally_xyz_thr_proxy(system->pair_ptr,k,i,system->N,0,0,0, fk_tmp[0],fk_tmp[1],fk_tmp[2], delki[0],delki[1],delki[2],thr); rvec_ScaledSum(delkj,1.,system->my_atoms[k].x,-1.,system->my_atoms[j].x); pair_reax_ptr->ev_tally_xyz_thr_proxy(system->pair_ptr,k,j,system->N,0,0,0, fk_tmp[0],fk_tmp[1],fk_tmp[2], delkj[0],delkj[1],delkj[2],thr); } } } /* ---------------------------------------------------------------------- */ void Add_dBond_to_Forces_NPTOMP( reax_system *system, int i, int pj, simulation_data *data, storage *workspace, reax_list **lists ) { reax_list *bonds = (*lists) + BONDS; bond_data *nbr_j, *nbr_k; bond_order_data *bo_ij, *bo_ji; dbond_coefficients coef; rvec temp, ext_press; ivec rel_box; int pk, k, j; - PairReaxCOMP *pair_reax_ptr = static_cast(system->pair_ptr); - #if defined(_OPENMP) int tid = omp_get_thread_num(); #else int tid = 0; #endif - ThrData *thr = pair_reax_ptr->getFixOMP()->get_thr(tid); long reductionOffset = (system->N * tid); /* Initializations */ nbr_j = &(bonds->select.bond_list[pj]); j = nbr_j->nbr; bo_ij = &(nbr_j->bo_data); bo_ji = &(bonds->select.bond_list[ nbr_j->sym_index ].bo_data); coef.C1dbo = bo_ij->C1dbo * (bo_ij->Cdbo + bo_ji->Cdbo); coef.C2dbo = bo_ij->C2dbo * (bo_ij->Cdbo + bo_ji->Cdbo); coef.C3dbo = bo_ij->C3dbo * (bo_ij->Cdbo + bo_ji->Cdbo); coef.C1dbopi = bo_ij->C1dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); coef.C2dbopi = bo_ij->C2dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); coef.C3dbopi = bo_ij->C3dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); coef.C4dbopi = bo_ij->C4dbopi * (bo_ij->Cdbopi + bo_ji->Cdbopi); coef.C1dbopi2 = bo_ij->C1dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); coef.C2dbopi2 = bo_ij->C2dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); coef.C3dbopi2 = bo_ij->C3dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); coef.C4dbopi2 = bo_ij->C4dbopi2 * (bo_ij->Cdbopi2 + bo_ji->Cdbopi2); coef.C1dDelta = bo_ij->C1dbo * (workspace->CdDelta[i]+workspace->CdDelta[j]); coef.C2dDelta = bo_ij->C2dbo * (workspace->CdDelta[i]+workspace->CdDelta[j]); coef.C3dDelta = bo_ij->C3dbo * (workspace->CdDelta[i]+workspace->CdDelta[j]); /************************************ * forces related to atom i * * first neighbors of atom i * ************************************/ for( pk = Start_Index(i, bonds); pk < End_Index(i, bonds); ++pk ) { nbr_k = &(bonds->select.bond_list[pk]); k = nbr_k->nbr; rvec_Scale(temp, -coef.C2dbo, nbr_k->bo_data.dBOp); /*2nd, dBO*/ rvec_ScaledAdd(temp, -coef.C2dDelta, nbr_k->bo_data.dBOp);/*dDelta*/ rvec_ScaledAdd(temp, -coef.C3dbopi, nbr_k->bo_data.dBOp); /*3rd, dBOpi*/ rvec_ScaledAdd(temp, -coef.C3dbopi2, nbr_k->bo_data.dBOp);/*3rd, dBOpi2*/ /* force */ rvec_Add(workspace->forceReduction[reductionOffset+k],temp ); /* pressure */ rvec_iMultiply( ext_press, nbr_k->rel_box, temp ); rvec_Add( workspace->my_ext_pressReduction[tid], ext_press ); } /* then atom i itself */ rvec_Scale( temp, coef.C1dbo, bo_ij->dBOp ); /*1st,dBO*/ rvec_ScaledAdd( temp, coef.C2dbo, workspace->dDeltap_self[i] ); /*2nd,dBO*/ rvec_ScaledAdd( temp, coef.C1dDelta, bo_ij->dBOp ); /*1st,dBO*/ rvec_ScaledAdd( temp, coef.C2dDelta, workspace->dDeltap_self[i] );/*2nd,dBO*/ rvec_ScaledAdd( temp, coef.C1dbopi, bo_ij->dln_BOp_pi ); /*1st,dBOpi*/ rvec_ScaledAdd( temp, coef.C2dbopi, bo_ij->dBOp ); /*2nd,dBOpi*/ rvec_ScaledAdd( temp, coef.C3dbopi, workspace->dDeltap_self[i]);/*3rd,dBOpi*/ rvec_ScaledAdd( temp, coef.C1dbopi2, bo_ij->dln_BOp_pi2 ); /*1st,dBO_pi2*/ rvec_ScaledAdd( temp, coef.C2dbopi2, bo_ij->dBOp ); /*2nd,dBO_pi2*/ rvec_ScaledAdd( temp, coef.C3dbopi2, workspace->dDeltap_self[i] );/*3rd*/ /* force */ rvec_Add(workspace->forceReduction[reductionOffset+i],temp ); for( pk = Start_Index(j, bonds); pk < End_Index(j, bonds); ++pk ) { nbr_k = &(bonds->select.bond_list[pk]); k = nbr_k->nbr; rvec_Scale( temp, -coef.C3dbo, nbr_k->bo_data.dBOp ); /*3rd,dBO*/ rvec_ScaledAdd( temp, -coef.C3dDelta, nbr_k->bo_data.dBOp);/*dDelta*/ rvec_ScaledAdd( temp, -coef.C4dbopi, nbr_k->bo_data.dBOp); /*4th,dBOpi*/ rvec_ScaledAdd( temp, -coef.C4dbopi2, nbr_k->bo_data.dBOp);/*4th,dBOpi2*/ /* force */ rvec_Add(workspace->forceReduction[reductionOffset+k],temp ); /* pressure */ if( k != i ) { ivec_Sum( rel_box, nbr_k->rel_box, nbr_j->rel_box ); //rel_box(k, i) rvec_iMultiply( ext_press, rel_box, temp ); rvec_Add( workspace->my_ext_pressReduction[tid], ext_press ); } } /* then atom j itself */ rvec_Scale( temp, -coef.C1dbo, bo_ij->dBOp ); /*1st, dBO*/ rvec_ScaledAdd( temp, coef.C3dbo, workspace->dDeltap_self[j] ); /*2nd, dBO*/ rvec_ScaledAdd( temp, -coef.C1dDelta, bo_ij->dBOp ); /*1st, dBO*/ rvec_ScaledAdd( temp, coef.C3dDelta, workspace->dDeltap_self[j]);/*2nd, dBO*/ rvec_ScaledAdd( temp, -coef.C1dbopi, bo_ij->dln_BOp_pi ); /*1st,dBOpi*/ rvec_ScaledAdd( temp, -coef.C2dbopi, bo_ij->dBOp ); /*2nd,dBOpi*/ rvec_ScaledAdd( temp, coef.C4dbopi, workspace->dDeltap_self[j]);/*3rd,dBOpi*/ rvec_ScaledAdd( temp, -coef.C1dbopi2, bo_ij->dln_BOp_pi2 ); /*1st,dBOpi2*/ rvec_ScaledAdd( temp, -coef.C2dbopi2, bo_ij->dBOp ); /*2nd,dBOpi2*/ rvec_ScaledAdd( temp,coef.C4dbopi2,workspace->dDeltap_self[j]);/*3rd,dBOpi2*/ /* force */ rvec_Add(workspace->forceReduction[reductionOffset+j],temp ); /* pressure */ rvec_iMultiply( ext_press, nbr_j->rel_box, temp ); rvec_Add( workspace->my_ext_pressReduction[tid], ext_press ); } /* ---------------------------------------------------------------------- */ int BOp_OMP( storage *workspace, reax_list *bonds, double bo_cut, int i, int btop_i, far_neighbor_data *nbr_pj, single_body_parameters *sbp_i, single_body_parameters *sbp_j, two_body_parameters *twbp, int btop_j, double C12, double C34, double C56, double BO, double BO_s, double BO_pi, double BO_pi2) { int j; double rr2; double Cln_BOp_s, Cln_BOp_pi, Cln_BOp_pi2; bond_data *ibond, *jbond; bond_order_data *bo_ij, *bo_ji; j = nbr_pj->nbr; rr2 = 1.0 / SQR(nbr_pj->d); // Top portion of BOp() moved to reaxc_forces_omp.cpp::Init_Forces_noQEq_OMP() /* Initially BO values are the uncorrected ones, page 1 */ /****** bonds i-j and j-i ******/ ibond = &( bonds->select.bond_list[btop_i] ); jbond = &( bonds->select.bond_list[btop_j] ); ibond->nbr = j; jbond->nbr = i; ibond->d = nbr_pj->d; jbond->d = nbr_pj->d; rvec_Copy( ibond->dvec, nbr_pj->dvec ); rvec_Scale( jbond->dvec, -1, nbr_pj->dvec ); ivec_Copy( ibond->rel_box, nbr_pj->rel_box ); ivec_Scale( jbond->rel_box, -1, nbr_pj->rel_box ); ibond->dbond_index = btop_i; jbond->dbond_index = btop_i; ibond->sym_index = btop_j; jbond->sym_index = btop_i; bo_ij = &( ibond->bo_data ); bo_ji = &( jbond->bo_data ); bo_ji->BO = bo_ij->BO = BO; bo_ji->BO_s = bo_ij->BO_s = BO_s; bo_ji->BO_pi = bo_ij->BO_pi = BO_pi; bo_ji->BO_pi2 = bo_ij->BO_pi2 = BO_pi2; /* Bond Order page2-3, derivative of total bond order prime */ Cln_BOp_s = twbp->p_bo2 * C12 * rr2; Cln_BOp_pi = twbp->p_bo4 * C34 * rr2; Cln_BOp_pi2 = twbp->p_bo6 * C56 * rr2; /* Only dln_BOp_xx wrt. dr_i is stored here, note that dln_BOp_xx/dr_i = -dln_BOp_xx/dr_j and all others are 0 */ rvec_Scale(bo_ij->dln_BOp_s,-bo_ij->BO_s*Cln_BOp_s,ibond->dvec); rvec_Scale(bo_ij->dln_BOp_pi,-bo_ij->BO_pi*Cln_BOp_pi,ibond->dvec); rvec_Scale(bo_ij->dln_BOp_pi2, -bo_ij->BO_pi2*Cln_BOp_pi2,ibond->dvec); rvec_Scale(bo_ji->dln_BOp_s, -1., bo_ij->dln_BOp_s); rvec_Scale(bo_ji->dln_BOp_pi, -1., bo_ij->dln_BOp_pi ); rvec_Scale(bo_ji->dln_BOp_pi2, -1., bo_ij->dln_BOp_pi2 ); rvec_Scale( bo_ij->dBOp, -(bo_ij->BO_s * Cln_BOp_s + bo_ij->BO_pi * Cln_BOp_pi + bo_ij->BO_pi2 * Cln_BOp_pi2), ibond->dvec ); rvec_Scale( bo_ji->dBOp, -1., bo_ij->dBOp ); bo_ij->BO_s -= bo_cut; bo_ij->BO -= bo_cut; bo_ji->BO_s -= bo_cut; bo_ji->BO -= bo_cut; bo_ij->Cdbo = bo_ij->Cdbopi = bo_ij->Cdbopi2 = 0.0; bo_ji->Cdbo = bo_ji->Cdbopi = bo_ji->Cdbopi2 = 0.0; return 1; } /* ---------------------------------------------------------------------- */ void BOOMP( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control ) { #ifdef OMP_TIMING double endTimeBase, startTimeBase; startTimeBase = MPI_Wtime(); #endif double p_lp1 = system->reax_param.gp.l[15]; - int num_bonds = 0; double p_boc1 = system->reax_param.gp.l[0]; double p_boc2 = system->reax_param.gp.l[1]; reax_list *bonds = (*lists) + BONDS; - int natoms = system->N; - int nthreads = control->nthreads; #if defined(_OPENMP) #pragma omp parallel default(shared) #endif { int i, j, pj, type_i, type_j; int start_i, end_i, sym_index; double val_i, Deltap_i, Deltap_boc_i; double val_j, Deltap_j, Deltap_boc_j; double f1, f2, f3, f4, f5, f4f5, exp_f4, exp_f5; double exp_p1i, exp_p2i, exp_p1j, exp_p2j, explp1; double temp, u1_ij, u1_ji, Cf1A_ij, Cf1B_ij, Cf1_ij, Cf1_ji; double Cf45_ij, Cf45_ji; //u_ij, u_ji double A0_ij, A1_ij, A2_ij, A2_ji, A3_ij, A3_ji; single_body_parameters *sbp_i, *sbp_j; two_body_parameters *twbp; bond_order_data *bo_ij, *bo_ji; -#if defined(_OPENMP) - int tid = omp_get_thread_num(); -#else - int tid = 0; -#endif /* Calculate Deltaprime, Deltaprime_boc values */ #if defined(_OPENMP) #pragma omp for schedule(static) #endif for (i = 0; i < system->N; ++i) { type_i = system->my_atoms[i].type; if(type_i < 0) continue; sbp_i = &(system->reax_param.sbp[type_i]); workspace->Deltap[i] = workspace->total_bond_order[i] - sbp_i->valency; workspace->Deltap_boc[i] = workspace->total_bond_order[i] - sbp_i->valency_val; workspace->total_bond_order[i] = 0; } // Wait till initialization complete #if defined(_OPENMP) #pragma omp barrier #endif /* Corrected Bond Order calculations */ #if defined(_OPENMP) #pragma omp for schedule(guided) #endif for (i = 0; i < system->N; ++i) { type_i = system->my_atoms[i].type; if(type_i < 0) continue; sbp_i = &(system->reax_param.sbp[type_i]); val_i = sbp_i->valency; Deltap_i = workspace->Deltap[i]; Deltap_boc_i = workspace->Deltap_boc[i]; start_i = Start_Index(i, bonds); end_i = End_Index(i, bonds); for (pj = start_i; pj < end_i; ++pj) { j = bonds->select.bond_list[pj].nbr; type_j = system->my_atoms[j].type; if(type_j < 0) continue; bo_ij = &( bonds->select.bond_list[pj].bo_data ); if( i < j || workspace->bond_mark[j] > 3) { twbp = &( system->reax_param.tbp[type_i][type_j] ); if( twbp->ovc < 0.001 && twbp->v13cor < 0.001 ) { bo_ij->C1dbo = 1.000000; bo_ij->C2dbo = 0.000000; bo_ij->C3dbo = 0.000000; bo_ij->C1dbopi = bo_ij->BO_pi; bo_ij->C2dbopi = 0.000000; bo_ij->C3dbopi = 0.000000; bo_ij->C4dbopi = 0.000000; bo_ij->C1dbopi2 = bo_ij->BO_pi2; bo_ij->C2dbopi2 = 0.000000; bo_ij->C3dbopi2 = 0.000000; bo_ij->C4dbopi2 = 0.000000; } else { val_j = system->reax_param.sbp[type_j].valency; Deltap_j = workspace->Deltap[j]; Deltap_boc_j = workspace->Deltap_boc[j]; /* on page 1 */ if( twbp->ovc >= 0.001 ) { /* Correction for overcoordination */ exp_p1i = exp( -p_boc1 * Deltap_i ); exp_p2i = exp( -p_boc2 * Deltap_i ); exp_p1j = exp( -p_boc1 * Deltap_j ); exp_p2j = exp( -p_boc2 * Deltap_j ); f2 = exp_p1i + exp_p1j; f3 = -1.0 / p_boc2 * log( 0.5 * ( exp_p2i + exp_p2j ) ); f1 = 0.5 * ( ( val_i + f2 )/( val_i + f2 + f3 ) + ( val_j + f2 )/( val_j + f2 + f3 ) ); /* Now come the derivates */ /* Bond Order pages 5-7, derivative of f1 */ temp = f2 + f3; u1_ij = val_i + temp; u1_ji = val_j + temp; Cf1A_ij = 0.5 * f3 * (1.0 / SQR( u1_ij ) + 1.0 / SQR( u1_ji )); Cf1B_ij = -0.5 * (( u1_ij - f3 ) / SQR( u1_ij ) + ( u1_ji - f3 ) / SQR( u1_ji )); Cf1_ij = 0.50 * ( -p_boc1 * exp_p1i / u1_ij - ((val_i+f2) / SQR(u1_ij)) * ( -p_boc1 * exp_p1i + exp_p2i / ( exp_p2i + exp_p2j ) ) + -p_boc1 * exp_p1i / u1_ji - ((val_j+f2) / SQR(u1_ji)) * ( -p_boc1 * exp_p1i + exp_p2i / ( exp_p2i + exp_p2j ) )); Cf1_ji = -Cf1A_ij * p_boc1 * exp_p1j + Cf1B_ij * exp_p2j / ( exp_p2i + exp_p2j ); } else { /* No overcoordination correction! */ f1 = 1.0; Cf1_ij = Cf1_ji = 0.0; } if( twbp->v13cor >= 0.001 ) { /* Correction for 1-3 bond orders */ exp_f4 =exp(-(twbp->p_boc4 * SQR( bo_ij->BO ) - Deltap_boc_i) * twbp->p_boc3 + twbp->p_boc5); exp_f5 =exp(-(twbp->p_boc4 * SQR( bo_ij->BO ) - Deltap_boc_j) * twbp->p_boc3 + twbp->p_boc5); f4 = 1. / (1. + exp_f4); f5 = 1. / (1. + exp_f5); f4f5 = f4 * f5; /* Bond Order pages 8-9, derivative of f4 and f5 */ Cf45_ij = -f4 * exp_f4; Cf45_ji = -f5 * exp_f5; } else { f4 = f5 = f4f5 = 1.0; Cf45_ij = Cf45_ji = 0.0; } /* Bond Order page 10, derivative of total bond order */ A0_ij = f1 * f4f5; A1_ij = -2 * twbp->p_boc3 * twbp->p_boc4 * bo_ij->BO * (Cf45_ij + Cf45_ji); A2_ij = Cf1_ij / f1 + twbp->p_boc3 * Cf45_ij; A2_ji = Cf1_ji / f1 + twbp->p_boc3 * Cf45_ji; A3_ij = A2_ij + Cf1_ij / f1; A3_ji = A2_ji + Cf1_ji / f1; /* find corrected bond orders and their derivative coef */ bo_ij->BO = bo_ij->BO * A0_ij; bo_ij->BO_pi = bo_ij->BO_pi * A0_ij *f1; bo_ij->BO_pi2= bo_ij->BO_pi2* A0_ij *f1; bo_ij->BO_s = bo_ij->BO - ( bo_ij->BO_pi + bo_ij->BO_pi2 ); bo_ij->C1dbo = A0_ij + bo_ij->BO * A1_ij; bo_ij->C2dbo = bo_ij->BO * A2_ij; bo_ij->C3dbo = bo_ij->BO * A2_ji; bo_ij->C1dbopi = f1*f1*f4*f5; bo_ij->C2dbopi = bo_ij->BO_pi * A1_ij; bo_ij->C3dbopi = bo_ij->BO_pi * A3_ij; bo_ij->C4dbopi = bo_ij->BO_pi * A3_ji; bo_ij->C1dbopi2 = f1*f1*f4*f5; bo_ij->C2dbopi2 = bo_ij->BO_pi2 * A1_ij; bo_ij->C3dbopi2 = bo_ij->BO_pi2 * A3_ij; bo_ij->C4dbopi2 = bo_ij->BO_pi2 * A3_ji; } /* neglect bonds that are < 1e-10 */ if( bo_ij->BO < 1e-10 ) bo_ij->BO = 0.0; if( bo_ij->BO_s < 1e-10 ) bo_ij->BO_s = 0.0; if( bo_ij->BO_pi < 1e-10 ) bo_ij->BO_pi = 0.0; if( bo_ij->BO_pi2 < 1e-10 ) bo_ij->BO_pi2 = 0.0; workspace->total_bond_order[i] += bo_ij->BO; //now keeps total_BO } // else { // /* We only need to update bond orders from bo_ji // everything else is set in uncorrected_bo calculations */ // sym_index = bonds->select.bond_list[pj].sym_index; // bo_ji = &(bonds->select.bond_list[ sym_index ].bo_data); // bo_ij->BO = bo_ji->BO; // bo_ij->BO_s = bo_ji->BO_s; // bo_ij->BO_pi = bo_ji->BO_pi; // bo_ij->BO_pi2 = bo_ji->BO_pi2; // workspace->total_bond_order[i] += bo_ij->BO;// now keeps total_BO // } } } // Wait for bo_ij to be updated #if defined(_OPENMP) #pragma omp barrier #endif // Try to combine the following for-loop back into the for-loop above /*-------------------------*/ #if defined(_OPENMP) #pragma omp for schedule(guided) #endif for (i = 0; i < system->N; ++i) { type_i = system->my_atoms[i].type; if(type_i < 0) continue; start_i = Start_Index(i, bonds); end_i = End_Index(i, bonds); for (pj = start_i; pj < end_i; ++pj) { j = bonds->select.bond_list[pj].nbr; type_j = system->my_atoms[j].type; if(type_j < 0) continue; if( i < j || workspace->bond_mark[j] > 3) { // Computed in previous for-loop } else { /* We only need to update bond orders from bo_ji everything else is set in uncorrected_bo calculations */ sym_index = bonds->select.bond_list[pj].sym_index; bo_ij = &( bonds->select.bond_list[pj].bo_data ); bo_ji = &(bonds->select.bond_list[ sym_index ].bo_data); bo_ij->BO = bo_ji->BO; bo_ij->BO_s = bo_ji->BO_s; bo_ij->BO_pi = bo_ji->BO_pi; bo_ij->BO_pi2 = bo_ji->BO_pi2; workspace->total_bond_order[i] += bo_ij->BO;// now keeps total_BO } } } /*-------------------------*/ // Need to wait for total_bond_order to be accumulated. #if defined(_OPENMP) #pragma omp barrier #endif /* Calculate some helper variables that are used at many places throughout force calculations */ #if defined(_OPENMP) #pragma omp for schedule(guided) #endif for(j = 0; j < system->N; ++j ) { type_j = system->my_atoms[j].type; if(type_j < 0) continue; sbp_j = &(system->reax_param.sbp[ type_j ]); workspace->Delta[j] = workspace->total_bond_order[j] - sbp_j->valency; workspace->Delta_e[j] = workspace->total_bond_order[j] - sbp_j->valency_e; workspace->Delta_boc[j] = workspace->total_bond_order[j] - sbp_j->valency_boc; workspace->Delta_val[j] = workspace->total_bond_order[j] - sbp_j->valency_val; workspace->vlpex[j] = workspace->Delta_e[j] - 2.0 * (int)(workspace->Delta_e[j]/2.0); explp1 = exp(-p_lp1 * SQR(2.0 + workspace->vlpex[j])); workspace->nlp[j] = explp1 - (int)(workspace->Delta_e[j] / 2.0); workspace->Delta_lp[j] = sbp_j->nlp_opt - workspace->nlp[j]; workspace->Clp[j] = 2.0 * p_lp1 * explp1 * (2.0 + workspace->vlpex[j]); workspace->dDelta_lp[j] = workspace->Clp[j]; if( sbp_j->mass > 21.0 ) { workspace->nlp_temp[j] = 0.5 * (sbp_j->valency_e - sbp_j->valency); workspace->Delta_lp_temp[j] = sbp_j->nlp_opt - workspace->nlp_temp[j]; workspace->dDelta_lp_temp[j] = 0.; } else { workspace->nlp_temp[j] = workspace->nlp[j]; workspace->Delta_lp_temp[j] = sbp_j->nlp_opt - workspace->nlp_temp[j]; workspace->dDelta_lp_temp[j] = workspace->Clp[j]; } } } // parallel region #ifdef OMP_TIMING endTimeBase = MPI_Wtime(); ompTimingData[COMPUTEBOINDEX] += (endTimeBase-startTimeBase); #endif } diff --git a/src/USER-OMP/reaxc_bonds_omp.cpp b/src/USER-OMP/reaxc_bonds_omp.cpp index dcf788a79..9e1691900 100644 --- a/src/USER-OMP/reaxc_bonds_omp.cpp +++ b/src/USER-OMP/reaxc_bonds_omp.cpp @@ -1,186 +1,184 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program Copyright (2010) Purdue University Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and Algorithmic Techniques", Parallel Computing, in press. 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 2 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: . ----------------------------------------------------------------------*/ #include "pair_reaxc_omp.h" #include "reaxc_bonds_omp.h" #include "reaxc_bond_orders_omp.h" #include "reaxc_list.h" #include "reaxc_tool_box.h" #include "reaxc_vector.h" #if defined(_OPENMP) #include #endif using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ void BondsOMP( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control ) { #ifdef OMP_TIMING double endTimeBase, startTimeBase; startTimeBase = MPI_Wtime(); #endif - int natoms = system->n; - int nthreads = control->nthreads; + const int natoms = system->n; reax_list *bonds = (*lists) + BONDS; - double gp3 = system->reax_param.gp.l[3]; - double gp4 = system->reax_param.gp.l[4]; - double gp7 = system->reax_param.gp.l[7]; - double gp10 = system->reax_param.gp.l[10]; - double gp37 = (int) system->reax_param.gp.l[37]; + const double gp3 = system->reax_param.gp.l[3]; + const double gp4 = system->reax_param.gp.l[4]; + const double gp7 = system->reax_param.gp.l[7]; + const double gp10 = system->reax_param.gp.l[10]; + const int gp37 = (int) system->reax_param.gp.l[37]; double total_Ebond = 0.0; #if defined(_OPENMP) #pragma omp parallel default(shared) reduction(+: total_Ebond) #endif { int i, j, pj; int start_i, end_i; int type_i, type_j; - double ebond, ebond_thr=0.0, pow_BOs_be2, exp_be12, CEbo; - double gp3, gp4, gp7, gp10, gp37; - double exphu, exphua1, exphub1, exphuov, hulpov, estriph, estriph_thr=0.0; + double ebond, pow_BOs_be2, exp_be12, CEbo; + double exphu, exphua1, exphub1, exphuov, hulpov, estriph; double decobdbo, decobdboua, decobdboub; single_body_parameters *sbp_i, *sbp_j; two_body_parameters *twbp; bond_order_data *bo_ij; #if defined(_OPENMP) int tid = omp_get_thread_num(); #else int tid = 0; #endif long reductionOffset = (system->N * tid); class PairReaxCOMP *pair_reax_ptr; pair_reax_ptr = static_cast(system->pair_ptr); class ThrData *thr = pair_reax_ptr->getFixOMP()->get_thr(tid); pair_reax_ptr->ev_setup_thr_proxy(system->pair_ptr->eflag_either, system->pair_ptr->vflag_either, natoms, system->pair_ptr->eatom, system->pair_ptr->vatom, thr); #if defined(_OPENMP) #pragma omp for schedule(guided) #endif for (i = 0; i < natoms; ++i) { start_i = Start_Index(i, bonds); end_i = End_Index(i, bonds); for (pj = start_i; pj < end_i; ++pj) { j = bonds->select.bond_list[pj].nbr; if( system->my_atoms[i].orig_id > system->my_atoms[j].orig_id ) continue; if( system->my_atoms[i].orig_id == system->my_atoms[j].orig_id ) { if (system->my_atoms[j].x[2] < system->my_atoms[i].x[2]) continue; if (system->my_atoms[j].x[2] == system->my_atoms[i].x[2] && system->my_atoms[j].x[1] < system->my_atoms[i].x[1]) continue; if (system->my_atoms[j].x[2] == system->my_atoms[i].x[2] && system->my_atoms[j].x[1] == system->my_atoms[i].x[1] && system->my_atoms[j].x[0] < system->my_atoms[i].x[0]) continue; } /* set the pointers */ type_i = system->my_atoms[i].type; type_j = system->my_atoms[j].type; sbp_i = &( system->reax_param.sbp[type_i] ); sbp_j = &( system->reax_param.sbp[type_j] ); twbp = &( system->reax_param.tbp[type_i][type_j] ); bo_ij = &( bonds->select.bond_list[pj].bo_data ); /* calculate the constants */ pow_BOs_be2 = pow( bo_ij->BO_s, twbp->p_be2 ); exp_be12 = exp( twbp->p_be1 * ( 1.0 - pow_BOs_be2 ) ); CEbo = -twbp->De_s * exp_be12 * ( 1.0 - twbp->p_be1 * twbp->p_be2 * pow_BOs_be2 ); /* calculate the Bond Energy */ total_Ebond += ebond = -twbp->De_s * bo_ij->BO_s * exp_be12 -twbp->De_p * bo_ij->BO_pi -twbp->De_pp * bo_ij->BO_pi2; /* tally into per-atom energy */ if (system->pair_ptr->evflag) pair_reax_ptr->ev_tally_thr_proxy(system->pair_ptr, i, j, natoms, 1, ebond, 0.0, 0.0, 0.0, 0.0, 0.0, thr); /* calculate derivatives of Bond Orders */ bo_ij->Cdbo += CEbo; bo_ij->Cdbopi -= (CEbo + twbp->De_p); bo_ij->Cdbopi2 -= (CEbo + twbp->De_pp); /* Stabilisation terminal triple bond */ if (bo_ij->BO >= 1.00) { if (gp37 == 2 || (sbp_i->mass == 12.0000 && sbp_j->mass == 15.9990) || (sbp_j->mass == 12.0000 && sbp_i->mass == 15.9990)) { exphu = exp( -gp7 * SQR(bo_ij->BO - 2.50) ); exphua1 = exp(-gp3 * (workspace->total_bond_order[i]-bo_ij->BO)); exphub1 = exp(-gp3 * (workspace->total_bond_order[j]-bo_ij->BO)); exphuov = exp(gp4 * (workspace->Delta[i] + workspace->Delta[j])); hulpov = 1.0 / (1.0 + 25.0 * exphuov); estriph = gp10 * exphu * hulpov * (exphua1 + exphub1); total_Ebond += estriph; decobdbo = gp10 * exphu * hulpov * (exphua1 + exphub1) * ( gp3 - 2.0 * gp7 * (bo_ij->BO-2.50) ); decobdboua = -gp10 * exphu * hulpov * (gp3*exphua1 + 25.0*gp4*exphuov*hulpov*(exphua1+exphub1)); decobdboub = -gp10 * exphu * hulpov * (gp3*exphub1 + 25.0*gp4*exphuov*hulpov*(exphua1+exphub1)); /* tally into per-atom energy */ if (system->pair_ptr->evflag) pair_reax_ptr->ev_tally_thr_proxy(system->pair_ptr, i, j, natoms, 1, estriph, 0.0, 0.0, 0.0, 0.0, 0.0, thr); bo_ij->Cdbo += decobdbo; workspace->CdDelta[i] += decobdboua; workspace->CdDeltaReduction[reductionOffset+j] += decobdboub; } } } } // for(i) } // omp data->my_en.e_bond += total_Ebond; #ifdef OMP_TIMING endTimeBase = MPI_Wtime(); ompTimingData[COMPUTEBONDSINDEX] += (endTimeBase-startTimeBase); #endif } diff --git a/src/USER-OMP/reaxc_forces_omp.cpp b/src/USER-OMP/reaxc_forces_omp.cpp index 4e37dac38..5e93f3112 100644 --- a/src/USER-OMP/reaxc_forces_omp.cpp +++ b/src/USER-OMP/reaxc_forces_omp.cpp @@ -1,649 +1,642 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program Copyright (2010) Purdue University Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and Algorithmic Techniques", Parallel Computing, in press. 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 2 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: . ----------------------------------------------------------------------*/ #include "pair_reaxc_omp.h" #include "thr_data.h" #include "reaxc_forces_omp.h" #include "reaxc_bond_orders_omp.h" #include "reaxc_bonds_omp.h" #include "reaxc_hydrogen_bonds_omp.h" #include "reaxc_io_tools.h" #include "reaxc_list.h" #include "reaxc_lookup.h" #include "reaxc_multi_body_omp.h" #include "reaxc_nonbonded_omp.h" #include "reaxc_tool_box.h" #include "reaxc_torsion_angles_omp.h" #include "reaxc_valence_angles_omp.h" #include "reaxc_vector.h" #if defined(_OPENMP) #include #endif using namespace LAMMPS_NS; // Functions defined in reaxc_forces.cpp extern interaction_function Interaction_Functions[]; extern double Compute_H(double, double, double*); extern double Compute_tabH(double, int, int); extern void Dummy_Interaction(reax_system*, control_params*, simulation_data*, storage*, reax_list**, output_controls*); /* ---------------------------------------------------------------------- */ void Init_Force_FunctionsOMP( control_params *control ) { Interaction_Functions[0] = BOOMP; Interaction_Functions[1] = BondsOMP; //Dummy_Interaction; Interaction_Functions[2] = Atom_EnergyOMP; //Dummy_Interaction; Interaction_Functions[3] = Valence_AnglesOMP; //Dummy_Interaction; Interaction_Functions[4] = Torsion_AnglesOMP; //Dummy_Interaction; if( control->hbond_cut > 0 ) Interaction_Functions[5] = Hydrogen_BondsOMP; else Interaction_Functions[5] = Dummy_Interaction; Interaction_Functions[6] = Dummy_Interaction; //empty Interaction_Functions[7] = Dummy_Interaction; //empty Interaction_Functions[8] = Dummy_Interaction; //empty Interaction_Functions[9] = Dummy_Interaction; //empty } /* ---------------------------------------------------------------------- */ // Only difference with MPI-only version is inclusion of OMP_TIMING statements void Compute_Bonded_ForcesOMP( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control, MPI_Comm comm ) { int i; #ifdef OMP_TIMING double startTimeBase, endTimeBase; startTimeBase = MPI_Wtime(); #endif /* Implement all force calls as function pointers */ for( i = 0; i < NUM_INTRS; i++ ) { (Interaction_Functions[i])( system, control, data, workspace, lists, out_control ); } #ifdef OMP_TIMING endTimeBase = MPI_Wtime(); ompTimingData[COMPUTEBFINDEX] += (endTimeBase-startTimeBase); #endif } // Only difference with MPI-only version is inclusion of OMP_TIMING statements void Compute_NonBonded_ForcesOMP( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control, MPI_Comm comm ) { /* van der Waals and Coulomb interactions */ #ifdef OMP_TIMING double endTimeBase, startTimeBase; startTimeBase = MPI_Wtime(); #endif if( control->tabulate == 0 ) vdW_Coulomb_Energy_OMP( system, control, data, workspace, lists, out_control ); else Tabulated_vdW_Coulomb_Energy_OMP( system, control, data, workspace, lists, out_control ); #ifdef OMP_TIMING endTimeBase = MPI_Wtime(); ompTimingData[COMPUTENBFINDEX] += (endTimeBase-startTimeBase); #endif } /* ---------------------------------------------------------------------- */ /* this version of Compute_Total_Force computes forces from coefficients accumulated by all interaction functions. Saves enormous time & space! */ void Compute_Total_ForceOMP( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, mpi_datatypes *mpi_data ) { #ifdef OMP_TIMING double startTimeBase,endTimeBase; startTimeBase = MPI_Wtime(); #endif int natoms = system->N; int nthreads = control->nthreads; long totalReductionSize = system->N * nthreads; reax_list *bonds = (*lists) + BONDS; #if defined(_OPENMP) #pragma omp parallel default(shared) //default(none) #endif { int i, j, k, pj, pk, start_j, end_j; #if defined(_OPENMP) int tid = omp_get_thread_num(); #else int tid = 0; #endif bond_order_data *bo_jk; class PairReaxCOMP *pair_reax_ptr; pair_reax_ptr = static_cast(system->pair_ptr); class ThrData *thr = pair_reax_ptr->getFixOMP()->get_thr(tid); pair_reax_ptr->ev_setup_thr_proxy(0, 1, natoms, system->pair_ptr->eatom, system->pair_ptr->vatom, thr); #if defined(_OPENMP) #pragma omp for schedule(guided) #endif for (i = 0; i < system->N; ++i) { for (j = 0; j < nthreads; ++j) workspace->CdDelta[i] += workspace->CdDeltaReduction[system->N*j+i]; } #if defined(_OPENMP) #pragma omp for schedule(dynamic,50) #endif for (j = 0; j < system->N; ++j) { start_j = Start_Index(j, bonds); end_j = End_Index(j, bonds); for (pk = start_j; pk < end_j; ++pk) { bo_jk = &( bonds->select.bond_list[pk].bo_data ); for (k = 0; k < nthreads; ++k) bo_jk->Cdbo += bo_jk->CdboReduction[k]; } } // #pragma omp for schedule(guided) //(dynamic,50) // for (i = 0; i < system->N; ++i) // for (pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj) // if (i < bonds->select.bond_list[pj].nbr) { // if (control->virial == 0) // Add_dBond_to_ForcesOMP( system, i, pj, workspace, lists ); // else // Add_dBond_to_Forces_NPTOMP(system, i, pj, data, workspace, lists ); // } if(control->virial == 0) { #if defined(_OPENMP) #pragma omp for schedule(dynamic,50) #endif for (i = 0; i < system->N; ++i) { const int startj = Start_Index(i, bonds); const int endj = End_Index(i, bonds); for (pj = startj; pj < endj; ++pj) if (i < bonds->select.bond_list[pj].nbr) Add_dBond_to_ForcesOMP( system, i, pj, workspace, lists ); } } else { #if defined(_OPENMP) #pragma omp for schedule(dynamic,50) #endif for (i = 0; i < system->N; ++i) { const int startj = Start_Index(i, bonds); const int endj = End_Index(i, bonds); for (pj = startj; pj < endj; ++pj) if (i < bonds->select.bond_list[pj].nbr) Add_dBond_to_Forces_NPTOMP(system, i, pj, data, workspace, lists ); } } // if(virial == 0) pair_reax_ptr->reduce_thr_proxy(system->pair_ptr, 0, 1, thr); #if defined(_OPENMP) #pragma omp for schedule(guided) #endif for (i = 0; i < system->N; ++i) { for (j = 0; j < nthreads; ++j) rvec_Add( workspace->f[i], workspace->forceReduction[system->N*j+i] ); } #if defined(_OPENMP) #pragma omp for schedule(guided) #endif for (i = 0; i < totalReductionSize; i++) { workspace->forceReduction[i][0] = 0; workspace->forceReduction[i][1] = 0; workspace->forceReduction[i][2] = 0; workspace->CdDeltaReduction[i] = 0; } } // parallel region if (control->virial) for (int i=0; i < nthreads; ++i) { rvec_Add(data->my_ext_press, workspace->my_ext_pressReduction[i]); workspace->my_ext_pressReduction[i][0] = 0; workspace->my_ext_pressReduction[i][1] = 0; workspace->my_ext_pressReduction[i][2] = 0; } #ifdef OMP_TIMING endTimeBase = MPI_Wtime(); ompTimingData[COMPUTETFINDEX] += (endTimeBase-startTimeBase); #endif } /* ---------------------------------------------------------------------- */ void Validate_ListsOMP( reax_system *system, storage *workspace, reax_list **lists, int step, int n, int N, int numH, MPI_Comm comm ) { int i, comp, Hindex; reax_list *bonds, *hbonds; - reallocate_data *realloc = &(workspace->realloc); double saferzone = system->saferzone; #if defined(_OPENMP) #pragma omp parallel default(shared) private(i, comp, Hindex) #endif { /* bond list */ if( N > 0 ) { bonds = *lists + BONDS; #if defined(_OPENMP) #pragma omp for schedule(guided) #endif for( i = 0; i < N; ++i ) { system->my_atoms[i].num_bonds = MAX(Num_Entries(i,bonds)*2, MIN_BONDS); if( i < N-1 ) comp = Start_Index(i+1, bonds); else comp = bonds->num_intrs; if( End_Index(i, bonds) > comp ) { fprintf( stderr, "step%d-bondchk failed: i=%d end(i)=%d str(i+1)=%d\n", step, i, End_Index(i,bonds), comp ); MPI_Abort( comm, INSUFFICIENT_MEMORY ); } } } /* hbonds list */ if( numH > 0 ) { hbonds = *lists + HBONDS; #if defined(_OPENMP) #pragma omp for schedule(guided) #endif for( i = 0; i < n; ++i ) { Hindex = system->my_atoms[i].Hindex; if( Hindex > -1 ) { system->my_atoms[i].num_hbonds = (int)(MAX( Num_Entries(Hindex, hbonds)*saferzone, MIN_HBONDS )); if( Hindex < numH-1 ) comp = Start_Index(Hindex+1, hbonds); else comp = hbonds->num_intrs; if( End_Index(Hindex, hbonds) > comp ) { fprintf(stderr,"step%d-hbondchk failed: H=%d end(H)=%d str(H+1)=%d\n", step, Hindex, End_Index(Hindex,hbonds), comp ); MPI_Abort( comm, INSUFFICIENT_MEMORY ); } } } } } // omp parallel } void Init_Forces_noQEq_OMP( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control, MPI_Comm comm ) { #ifdef OMP_TIMING double startTimeBase, endTimeBase; startTimeBase = MPI_Wtime(); #endif - int i, j, pi, pj; - int start_i, end_i, start_j, end_j; + int i, j, pj; + int start_i, end_i; int type_i, type_j; int ihb, jhb, ihb_top, jhb_top; - int local, flag; - double r_ij, cutoff; + double cutoff; single_body_parameters *sbp_i, *sbp_j; two_body_parameters *twbp; far_neighbor_data *nbr_pj; reax_atom *atom_i, *atom_j; - bond_data *ibond, *jbond; reax_list *far_nbrs = *lists + FAR_NBRS; reax_list *bonds = *lists + BONDS; reax_list *hbonds = *lists + HBONDS; int num_bonds = 0; int num_hbonds = 0; int btop_i = 0; - int btop_j = 0; - int renbr = (data->step-data->prev_steps) % control->reneighbor == 0; // We will use CdDeltaReduction as a temporary (double) buffer to accumulate total_bond_order // This is safe because CdDeltaReduction is currently zeroed and its accumulation doesn't start until BondsOMP() double * tmp_bond_order = workspace->CdDeltaReduction; // We do the same with forceReduction as a temporary (rvec) buffer to accumulate dDeltap_self // This is safe because forceReduction is currently zeroed and its accumulation does start until Hydrogen_BondsOMP() rvec * tmp_ddelta = workspace->forceReduction; /* uncorrected bond orders */ cutoff = control->bond_cut; #if defined(_OPENMP) #pragma omp parallel default(shared) \ - private(i, atom_i, type_i, pi, start_i, end_i, sbp_i, btop_i, ibond, ihb, ihb_top, \ - j, atom_j, type_j, pj, start_j, end_j, sbp_j, nbr_pj, jbond, jhb, twbp) + private(i, atom_i, type_i, start_i, end_i, sbp_i, btop_i, ihb, ihb_top, \ + j, atom_j, type_j, pj, sbp_j, nbr_pj, jhb, twbp) #endif { int nthreads = control->nthreads; #if defined(_OPENMP) int tid = omp_get_thread_num(); #else int tid = 0; #endif long reductionOffset = system->N * tid; long totalReductionSize = system->N * nthreads; #if defined(_OPENMP) #pragma omp for schedule(dynamic,50) reduction(+ : num_bonds) #endif for (i = 0; i < system->N; ++i) { atom_i = &(system->my_atoms[i]); type_i = atom_i->type; sbp_i = &(system->reax_param.sbp[type_i]); start_i = Start_Index(i, far_nbrs); end_i = End_Index(i, far_nbrs); for( pj = start_i; pj < end_i; ++pj ) { nbr_pj = &( far_nbrs->select.far_nbr_list[pj] ); if (nbr_pj->d <= cutoff) { j = nbr_pj->nbr; atom_j = &(system->my_atoms[j]); type_j = atom_j->type; sbp_j = &(system->reax_param.sbp[type_j]); twbp = &(system->reax_param.tbp[type_i][type_j]); // #pragma omp critical // { // btop_i = End_Index(i, bonds); // if( BOp(workspace, bonds, control->bo_cut, i, btop_i, nbr_pj, sbp_i, sbp_j, twbp) ) { // num_bonds++; // btop_i++; // Set_End_Index(i, btop_i, bonds); // } // } // Trying to minimize time spent in critical section by moving initial part of BOp() // outside of critical section. // Start top portion of BOp() - int jj = nbr_pj->nbr; double C12, C34, C56; double BO, BO_s, BO_pi, BO_pi2; double bo_cut = control->bo_cut; if( sbp_i->r_s > 0.0 && sbp_j->r_s > 0.0 ) { C12 = twbp->p_bo1 * pow( nbr_pj->d / twbp->r_s, twbp->p_bo2 ); BO_s = (1.0 + bo_cut) * exp( C12 ); } else BO_s = C12 = 0.0; if( sbp_i->r_pi > 0.0 && sbp_j->r_pi > 0.0 ) { C34 = twbp->p_bo3 * pow( nbr_pj->d / twbp->r_p, twbp->p_bo4 ); BO_pi = exp( C34 ); } else BO_pi = C34 = 0.0; if( sbp_i->r_pi_pi > 0.0 && sbp_j->r_pi_pi > 0.0 ) { C56 = twbp->p_bo5 * pow( nbr_pj->d / twbp->r_pp, twbp->p_bo6 ); BO_pi2= exp( C56 ); } else BO_pi2 = C56 = 0.0; /* Initially BO values are the uncorrected ones, page 1 */ BO = BO_s + BO_pi + BO_pi2; // End top portion of BOp() if(BO >= bo_cut) { int btop_j; // Update indices in critical section #if defined(_OPENMP) #pragma omp critical #endif { btop_i = End_Index( i, bonds ); btop_j = End_Index( j, bonds ); Set_End_Index( j, btop_j+1, bonds ); Set_End_Index( i, btop_i+1, bonds ); } // omp critical // Finish remaining BOp() work BOp_OMP(workspace, bonds, bo_cut, i , btop_i, nbr_pj, sbp_i, sbp_j, twbp, btop_j, C12, C34, C56, BO, BO_s, BO_pi, BO_pi2); bond_data * ibond = &(bonds->select.bond_list[btop_i]); bond_order_data * bo_ij = &(ibond->bo_data); bond_data * jbond = &(bonds->select.bond_list[btop_j]); bond_order_data * bo_ji = &(jbond->bo_data); workspace->total_bond_order[i] += bo_ij->BO; tmp_bond_order[reductionOffset + j] += bo_ji->BO; rvec_Add(workspace->dDeltap_self[i], bo_ij->dBOp); rvec_Add(tmp_ddelta[reductionOffset + j], bo_ji->dBOp); btop_i++; num_bonds++; } // if(BO>=bo_cut) } // if(cutoff) } // for(pj) } // for(i) // Need to wait for all indices and tmp arrays accumulated. #if defined(_OPENMP) #pragma omp barrier #endif #if defined(_OPENMP) #pragma omp for schedule(dynamic,50) #endif for(i=0; iN; i++) for(int t=0; tN + i; workspace->dDeltap_self[i][0] += tmp_ddelta[indx][0]; workspace->dDeltap_self[i][1] += tmp_ddelta[indx][1]; workspace->dDeltap_self[i][2] += tmp_ddelta[indx][2]; workspace->total_bond_order[i] += tmp_bond_order[indx]; } /* hydrogen bond list */ if (control->hbond_cut > 0) { cutoff = control->hbond_cut; #if defined(_OPENMP) #pragma omp for schedule(dynamic,50) reduction(+ : num_hbonds) #endif for (i = 0; i < system->n; ++i) { atom_i = &(system->my_atoms[i]); type_i = atom_i->type; sbp_i = &(system->reax_param.sbp[type_i]); ihb = sbp_i->p_hbond; #if defined(_OPENMP) #pragma omp critical #endif { if (ihb == 1 || ihb == 2) { start_i = Start_Index(i, far_nbrs); end_i = End_Index(i, far_nbrs); for (pj = start_i; pj < end_i; ++pj) { nbr_pj = &( far_nbrs->select.far_nbr_list[pj] ); j = nbr_pj->nbr; atom_j = &(system->my_atoms[j]); type_j = atom_j->type; if(type_j < 0) continue; sbp_j = &(system->reax_param.sbp[type_j]); jhb = sbp_j->p_hbond; if (nbr_pj->d <= control->hbond_cut) { int iflag = 0; int jflag = 0; if(ihb==1 && jhb==2) iflag = 1; else if(jn && ihb == 2 && jhb == 1) jflag = 1; if(iflag || jflag) { if(iflag) { ihb_top = End_Index(atom_i->Hindex, hbonds); Set_End_Index(atom_i->Hindex, ihb_top+1, hbonds); } else if(jflag) { jhb_top = End_Index(atom_j->Hindex, hbonds); Set_End_Index(atom_j->Hindex, jhb_top+1, hbonds); } if(iflag) { hbonds->select.hbond_list[ihb_top].nbr = j; hbonds->select.hbond_list[ihb_top].scl = 1; hbonds->select.hbond_list[ihb_top].ptr = nbr_pj; } else if(jflag) { hbonds->select.hbond_list[jhb_top].nbr = i; hbonds->select.hbond_list[jhb_top].scl = -1; hbonds->select.hbond_list[jhb_top].ptr = nbr_pj; } num_hbonds++; } // if(iflag || jflag) } } } } // omp critical } } // if(control->hbond > 0) // Zero buffers for others to use as intended. #if defined(_OPENMP) #pragma omp for schedule(guided) #endif for(i=0; irealloc.num_bonds = num_bonds; workspace->realloc.num_hbonds = num_hbonds; Validate_ListsOMP( system, workspace, lists, data->step, system->n, system->N, system->numH, comm ); #ifdef OMP_TIMING endTimeBase = MPI_Wtime(); ompTimingData[COMPUTEIFINDEX] += (endTimeBase-startTimeBase); #endif } /* ---------------------------------------------------------------------- */ void Compute_ForcesOMP( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control, mpi_datatypes *mpi_data ) { - int qeq_flag; MPI_Comm comm = mpi_data->world; // Init Forces #if defined(LOG_PERFORMANCE) double t_start = 0; if( system->my_rank == MASTER_NODE ) t_start = Get_Time( ); #endif Init_Forces_noQEq_OMP( system, control, data, workspace, lists, out_control, comm ); #if defined(LOG_PERFORMANCE) //MPI_Barrier( comm ); if( system->my_rank == MASTER_NODE ) Update_Timing_Info( &t_start, &(data->timing.init_forces) ); #endif // Bonded Interactions Compute_Bonded_ForcesOMP( system, control, data, workspace, lists, out_control, mpi_data->world ); #if defined(LOG_PERFORMANCE) if( system->my_rank == MASTER_NODE ) Update_Timing_Info( &t_start, &(data->timing.bonded) ); #endif // Nonbonded Interactions Compute_NonBonded_ForcesOMP( system, control, data, workspace, lists, out_control, mpi_data->world ); #if defined(LOG_PERFORMANCE) if( system->my_rank == MASTER_NODE ) Update_Timing_Info( &t_start, &(data->timing.nonb) ); #endif // Total Force Compute_Total_ForceOMP( system, control, data, workspace, lists, mpi_data ); #if defined(LOG_PERFORMANCE) if( system->my_rank == MASTER_NODE ) Update_Timing_Info( &t_start, &(data->timing.bonded) ); #endif } diff --git a/src/USER-OMP/reaxc_multi_body_omp.cpp b/src/USER-OMP/reaxc_multi_body_omp.cpp index acbe4ec26..ff8baa3c1 100644 --- a/src/USER-OMP/reaxc_multi_body_omp.cpp +++ b/src/USER-OMP/reaxc_multi_body_omp.cpp @@ -1,297 +1,295 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program Copyright (2010) Purdue University Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and Algorithmic Techniques", Parallel Computing, in press. 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 2 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: . ----------------------------------------------------------------------*/ #include "pair_reaxc_omp.h" #include "thr_data.h" #include "reaxc_multi_body_omp.h" #include "reaxc_bond_orders_omp.h" #include "reaxc_list.h" #include "reaxc_vector.h" #if defined(_OPENMP) #include #endif using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ void Atom_EnergyOMP( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control ) { #ifdef OMP_TIMING double endTimeBase, startTimeBase; startTimeBase = MPI_Wtime(); #endif /* Initialize parameters */ - double p_lp1 = system->reax_param.gp.l[15]; - double p_lp3 = system->reax_param.gp.l[5]; - double p_ovun3 = system->reax_param.gp.l[32]; - double p_ovun4 = system->reax_param.gp.l[31]; - double p_ovun6 = system->reax_param.gp.l[6]; - double p_ovun7 = system->reax_param.gp.l[8]; - double p_ovun8 = system->reax_param.gp.l[9]; - - int natoms = system->n; - int nthreads = control->nthreads; + const double p_lp3 = system->reax_param.gp.l[5]; + const double p_ovun3 = system->reax_param.gp.l[32]; + const double p_ovun4 = system->reax_param.gp.l[31]; + const double p_ovun6 = system->reax_param.gp.l[6]; + const double p_ovun7 = system->reax_param.gp.l[8]; + const double p_ovun8 = system->reax_param.gp.l[9]; + + const int natoms = system->n; reax_list *bonds = (*lists) + BONDS; double total_Elp = 0.0; double total_Eun = 0.0; double total_Eov = 0.0; #if defined(_OPENMP) #pragma omp parallel default(shared) reduction(+:total_Elp, total_Eun, total_Eov) #endif { int i, j, pj, type_i, type_j; double Delta_lpcorr, dfvl; double e_lp, expvd2, inv_expvd2, dElp, CElp, DlpVi; double e_lph, Di, vov3, deahu2dbo, deahu2dsbo; double e_ov, CEover1, CEover2, CEover3, CEover4; double exp_ovun1, exp_ovun2, sum_ovun1, sum_ovun2; double exp_ovun2n, exp_ovun6, exp_ovun8; double inv_exp_ovun1, inv_exp_ovun2, inv_exp_ovun2n, inv_exp_ovun8; double e_un, CEunder1, CEunder2, CEunder3, CEunder4; - double eng_tmp, f_tmp; + double eng_tmp; double p_lp2, p_ovun2, p_ovun5; int numbonds; - single_body_parameters *sbp_i, *sbp_j; + single_body_parameters *sbp_i; two_body_parameters *twbp; bond_data *pbond; bond_order_data *bo_ij; #if defined(_OPENMP) int tid = omp_get_thread_num(); #else int tid = 0; #endif long reductionOffset = (system->N * tid); class PairReaxCOMP *pair_reax_ptr; pair_reax_ptr = static_cast(system->pair_ptr); class ThrData *thr = pair_reax_ptr->getFixOMP()->get_thr(tid); pair_reax_ptr->ev_setup_thr_proxy(system->pair_ptr->eflag_either, system->pair_ptr->vflag_either, natoms, system->pair_ptr->eatom, system->pair_ptr->vatom, thr); #if defined(_OPENMP) #pragma omp for schedule(guided) #endif for ( i = 0; i < system->n; ++i) { type_i = system->my_atoms[i].type; if(type_i < 0) continue; sbp_i = &(system->reax_param.sbp[ type_i ]); /* lone-pair Energy */ p_lp2 = sbp_i->p_lp2; expvd2 = exp( -75 * workspace->Delta_lp[i] ); inv_expvd2 = 1. / (1. + expvd2 ); numbonds = 0; e_lp = 0.0; for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) numbonds ++; /* calculate the energy */ if(numbonds > 0) total_Elp += e_lp = p_lp2 * workspace->Delta_lp[i] * inv_expvd2; dElp = p_lp2 * inv_expvd2 + 75 * p_lp2 * workspace->Delta_lp[i] * expvd2 * SQR(inv_expvd2); CElp = dElp * workspace->dDelta_lp[i]; if(numbonds > 0) workspace->CdDelta[i] += CElp; // lp - 1st term /* tally into per-atom energy */ if( system->pair_ptr->evflag) pair_reax_ptr->ev_tally_thr_proxy(system->pair_ptr, i, i, system->n, 1, e_lp, 0.0, 0.0, 0.0, 0.0, 0.0, thr); /* correction for C2 */ if( p_lp3 > 0.001 && !strcmp(system->reax_param.sbp[type_i].name, "C") ) for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) { j = bonds->select.bond_list[pj].nbr; type_j = system->my_atoms[j].type; if(type_j < 0) continue; if( !strcmp( system->reax_param.sbp[type_j].name, "C" ) ) { twbp = &( system->reax_param.tbp[type_i][type_j]); bo_ij = &( bonds->select.bond_list[pj].bo_data ); Di = workspace->Delta[i]; vov3 = bo_ij->BO - Di - 0.040*pow(Di, 4.); if( vov3 > 3. ) { total_Elp += e_lph = p_lp3 * SQR(vov3-3.0); deahu2dbo = 2.*p_lp3*(vov3 - 3.); deahu2dsbo = 2.*p_lp3*(vov3 - 3.)*(-1. - 0.16*pow(Di, 3.)); bo_ij->Cdbo += deahu2dbo; workspace->CdDelta[i] += deahu2dsbo; /* tally into per-atom energy */ if( system->pair_ptr->evflag) pair_reax_ptr->ev_tally_thr_proxy(system->pair_ptr, i, j, system->n, 1, e_lph, 0.0, 0.0, 0.0, 0.0, 0.0, thr); } } } } #if defined(_OPENMP) #pragma omp barrier #pragma omp for schedule(guided) #endif for (i = 0; i < system->n; ++i) { type_i = system->my_atoms[i].type; if(type_i < 0) continue; sbp_i = &(system->reax_param.sbp[ type_i ]); /* over-coordination energy */ if( sbp_i->mass > 21.0 ) dfvl = 0.0; else dfvl = 1.0; // only for 1st-row elements p_ovun2 = sbp_i->p_ovun2; sum_ovun1 = sum_ovun2 = 0; for (pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj) { j = bonds->select.bond_list[pj].nbr; type_j = system->my_atoms[j].type; if(type_j < 0) continue; bo_ij = &(bonds->select.bond_list[pj].bo_data); twbp = &(system->reax_param.tbp[ type_i ][ type_j ]); sum_ovun1 += twbp->p_ovun1 * twbp->De_s * bo_ij->BO; sum_ovun2 += (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j])* ( bo_ij->BO_pi + bo_ij->BO_pi2 ); } exp_ovun1 = p_ovun3 * exp( p_ovun4 * sum_ovun2 ); inv_exp_ovun1 = 1.0 / (1 + exp_ovun1); Delta_lpcorr = workspace->Delta[i] - (dfvl * workspace->Delta_lp_temp[i]) * inv_exp_ovun1; exp_ovun2 = exp( p_ovun2 * Delta_lpcorr ); inv_exp_ovun2 = 1.0 / (1.0 + exp_ovun2); DlpVi = 1.0 / (Delta_lpcorr + sbp_i->valency + 1e-8); CEover1 = Delta_lpcorr * DlpVi * inv_exp_ovun2; total_Eov += e_ov = sum_ovun1 * CEover1; CEover2 = sum_ovun1 * DlpVi * inv_exp_ovun2 * (1.0 - Delta_lpcorr * ( DlpVi + p_ovun2 * exp_ovun2 * inv_exp_ovun2 )); CEover3 = CEover2 * (1.0 - dfvl * workspace->dDelta_lp[i] * inv_exp_ovun1 ); CEover4 = CEover2 * (dfvl * workspace->Delta_lp_temp[i]) * p_ovun4 * exp_ovun1 * SQR(inv_exp_ovun1); /* under-coordination potential */ p_ovun2 = sbp_i->p_ovun2; p_ovun5 = sbp_i->p_ovun5; exp_ovun2n = 1.0 / exp_ovun2; exp_ovun6 = exp( p_ovun6 * Delta_lpcorr ); exp_ovun8 = p_ovun7 * exp(p_ovun8 * sum_ovun2); inv_exp_ovun2n = 1.0 / (1.0 + exp_ovun2n); inv_exp_ovun8 = 1.0 / (1.0 + exp_ovun8); numbonds = 0; e_un = 0.0; for( pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj ) numbonds ++; if(numbonds > 0) total_Eun += e_un = -p_ovun5 * (1.0 - exp_ovun6) * inv_exp_ovun2n * inv_exp_ovun8; CEunder1 = inv_exp_ovun2n * ( p_ovun5 * p_ovun6 * exp_ovun6 * inv_exp_ovun8 + p_ovun2 * e_un * exp_ovun2n ); CEunder2 = -e_un * p_ovun8 * exp_ovun8 * inv_exp_ovun8; CEunder3 = CEunder1 * (1.0 - dfvl*workspace->dDelta_lp[i]*inv_exp_ovun1); CEunder4 = CEunder1 * (dfvl*workspace->Delta_lp_temp[i]) * p_ovun4 * exp_ovun1 * SQR(inv_exp_ovun1) + CEunder2; /* tally into per-atom energy */ if (system->pair_ptr->evflag) { eng_tmp = e_ov; if(numbonds > 0) eng_tmp+= e_un; pair_reax_ptr->ev_tally_thr_proxy(system->pair_ptr, i, i, system->n, 1, eng_tmp, 0.0, 0.0, 0.0, 0.0, 0.0, thr); } /* forces */ workspace->CdDelta[i] += CEover3; // OvCoor - 2nd term if(numbonds > 0) workspace->CdDelta[i] += CEunder3; // UnCoor - 1st term for (pj = Start_Index(i, bonds); pj < End_Index(i, bonds); ++pj) { pbond = &(bonds->select.bond_list[pj]); j = pbond->nbr; bo_ij = &(pbond->bo_data); twbp = &(system->reax_param.tbp[ system->my_atoms[i].type ] [system->my_atoms[pbond->nbr].type]); bo_ij->Cdbo += CEover1 * twbp->p_ovun1 * twbp->De_s; // OvCoor-1st workspace->CdDeltaReduction[reductionOffset+j] += CEover4 * (1.0 - dfvl*workspace->dDelta_lp[j]) * (bo_ij->BO_pi + bo_ij->BO_pi2); // OvCoor-3a bo_ij->Cdbopi += CEover4 * (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j]); // OvCoor-3b bo_ij->Cdbopi2 += CEover4 * (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j]); // OvCoor-3b workspace->CdDeltaReduction[reductionOffset+j] += CEunder4 * (1.0 - dfvl*workspace->dDelta_lp[j]) * (bo_ij->BO_pi + bo_ij->BO_pi2); // UnCoor - 2a bo_ij->Cdbopi += CEunder4 * (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j]); // UnCoor-2b bo_ij->Cdbopi2 += CEunder4 * (workspace->Delta[j] - dfvl*workspace->Delta_lp_temp[j]); // UnCoor-2b } } pair_reax_ptr->reduce_thr_proxy(system->pair_ptr, system->pair_ptr->eflag_either, system->pair_ptr->vflag_either, thr); } data->my_en.e_lp += total_Elp; data->my_en.e_ov += total_Eov; data->my_en.e_un += total_Eun; #ifdef OMP_TIMING endTimeBase = MPI_Wtime(); ompTimingData[COMPUTEATOMENERGYINDEX] += (endTimeBase-startTimeBase); #endif } diff --git a/src/USER-OMP/reaxc_nonbonded_omp.cpp b/src/USER-OMP/reaxc_nonbonded_omp.cpp index 38a6d9e86..c509be8a2 100644 --- a/src/USER-OMP/reaxc_nonbonded_omp.cpp +++ b/src/USER-OMP/reaxc_nonbonded_omp.cpp @@ -1,400 +1,396 @@ /*---------------------------------------------------------------------- PuReMD - Purdue ReaxFF Molecular Dynamics Program Copyright (2010) Purdue University Hasan Metin Aktulga, hmaktulga@lbl.gov Joseph Fogarty, jcfogart@mail.usf.edu Sagar Pandit, pandit@usf.edu Ananth Y Grama, ayg@cs.purdue.edu Please cite the related publication: H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama, "Parallel Reactive Molecular Dynamics: Numerical Methods and Algorithmic Techniques", Parallel Computing, in press. 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 2 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: . ----------------------------------------------------------------------*/ #include "pair_reaxc_omp.h" #include "thr_data.h" #include "reaxc_types.h" #include "reaxc_nonbonded.h" #include "reaxc_nonbonded_omp.h" #include "reaxc_bond_orders_omp.h" #include "reaxc_list.h" #include "reaxc_vector.h" #if defined(_OPENMP) #include #endif using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ void vdW_Coulomb_Energy_OMP( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control ) { int natoms = system->n; - int nthreads = control->nthreads; - long totalReductionSize = system->N * nthreads; reax_list *far_nbrs = (*lists) + FAR_NBRS; double p_vdW1 = system->reax_param.gp.l[28]; double p_vdW1i = 1.0 / p_vdW1; double total_EvdW = 0.; double total_Eele = 0.; #if defined(_OPENMP) #pragma omp parallel default(shared) reduction(+: total_EvdW, total_Eele) #endif { #if defined(_OPENMP) int tid = omp_get_thread_num(); #else int tid = 0; #endif int i, j, pj; int start_i, end_i, orig_i, orig_j, flag; double powr_vdW1, powgi_vdW1; double tmp, r_ij, fn13, exp1, exp2; double Tap, dTap, dfn13, CEvd, CEclmb, de_core; double dr3gamij_1, dr3gamij_3; - double e_ele, e_ele_thr, e_vdW, e_vdW_thr, e_core, SMALL = 0.0001; + double e_ele, e_vdW, e_core; + const double SMALL = 0.0001; double e_lg, de_lg, r_ij5, r_ij6, re6; rvec temp, ext_press; two_body_parameters *twbp; far_neighbor_data *nbr_pj; // Tallying variables: double pe_vdw, f_tmp, delij[3]; long reductionOffset = (system->N * tid); class PairReaxCOMP *pair_reax_ptr; pair_reax_ptr = static_cast(system->pair_ptr); class ThrData *thr = pair_reax_ptr->getFixOMP()->get_thr(tid); pair_reax_ptr->ev_setup_thr_proxy(system->pair_ptr->eflag_either, system->pair_ptr->vflag_either, natoms, system->pair_ptr->eatom, system->pair_ptr->vatom, thr); e_core = 0; e_vdW = 0; - e_vdW_thr = 0; e_lg = 0; de_lg = 0.0; #if defined(_OPENMP) #pragma omp for schedule(guided) #endif for( i = 0; i < natoms; ++i ) { if(system->my_atoms[i].type < 0) continue; start_i = Start_Index(i, far_nbrs); end_i = End_Index(i, far_nbrs); orig_i = system->my_atoms[i].orig_id; for( pj = start_i; pj < end_i; ++pj ) { nbr_pj = &(far_nbrs->select.far_nbr_list[pj]); j = nbr_pj->nbr; orig_j = system->my_atoms[j].orig_id; flag = 0; if(nbr_pj->d <= control->nonb_cut) { if(j < natoms) flag = 1; else if (orig_i < orig_j) flag = 1; else if (orig_i == orig_j) { if (nbr_pj->dvec[2] > SMALL) flag = 1; else if (fabs(nbr_pj->dvec[2]) < SMALL) { if (nbr_pj->dvec[1] > SMALL) flag = 1; else if (fabs(nbr_pj->dvec[1]) < SMALL && nbr_pj->dvec[0] > SMALL) flag = 1; } } } if (flag) { r_ij = nbr_pj->d; twbp = &(system->reax_param.tbp[ system->my_atoms[i].type ] [ system->my_atoms[j].type ]); /* Calculate Taper and its derivative */ // Tap = nbr_pj->Tap; -- precomputed during compte_H Tap = workspace->Tap[7] * r_ij + workspace->Tap[6]; Tap = Tap * r_ij + workspace->Tap[5]; Tap = Tap * r_ij + workspace->Tap[4]; Tap = Tap * r_ij + workspace->Tap[3]; Tap = Tap * r_ij + workspace->Tap[2]; Tap = Tap * r_ij + workspace->Tap[1]; Tap = Tap * r_ij + workspace->Tap[0]; dTap = 7*workspace->Tap[7] * r_ij + 6*workspace->Tap[6]; dTap = dTap * r_ij + 5*workspace->Tap[5]; dTap = dTap * r_ij + 4*workspace->Tap[4]; dTap = dTap * r_ij + 3*workspace->Tap[3]; dTap = dTap * r_ij + 2*workspace->Tap[2]; dTap += workspace->Tap[1]/r_ij; /*vdWaals Calculations*/ if(system->reax_param.gp.vdw_type==1 || system->reax_param.gp.vdw_type==3) { // shielding powr_vdW1 = pow(r_ij, p_vdW1); powgi_vdW1 = pow( 1.0 / twbp->gamma_w, p_vdW1); fn13 = pow( powr_vdW1 + powgi_vdW1, p_vdW1i ); exp1 = exp( twbp->alpha * (1.0 - fn13 / twbp->r_vdW) ); exp2 = exp( 0.5 * twbp->alpha * (1.0 - fn13 / twbp->r_vdW) ); e_vdW = twbp->D * (exp1 - 2.0 * exp2); total_EvdW += Tap * e_vdW; dfn13 = pow( powr_vdW1 + powgi_vdW1, p_vdW1i - 1.0) * pow(r_ij, p_vdW1 - 2.0); CEvd = dTap * e_vdW - Tap * twbp->D * (twbp->alpha / twbp->r_vdW) * (exp1 - exp2) * dfn13; } else{ // no shielding exp1 = exp( twbp->alpha * (1.0 - r_ij / twbp->r_vdW) ); exp2 = exp( 0.5 * twbp->alpha * (1.0 - r_ij / twbp->r_vdW) ); e_vdW = twbp->D * (exp1 - 2.0 * exp2); total_EvdW += Tap * e_vdW; CEvd = dTap * e_vdW - Tap * twbp->D * (twbp->alpha / twbp->r_vdW) * (exp1 - exp2) / r_ij; } if(system->reax_param.gp.vdw_type==2 || system->reax_param.gp.vdw_type==3) { // innner wall e_core = twbp->ecore * exp(twbp->acore * (1.0-(r_ij/twbp->rcore))); total_EvdW += Tap * e_core; de_core = -(twbp->acore/twbp->rcore) * e_core; CEvd += dTap * e_core + Tap * de_core / r_ij; // lg correction, only if lgvdw is yes if (control->lgflag) { r_ij5 = pow( r_ij, 5.0 ); r_ij6 = pow( r_ij, 6.0 ); re6 = pow( twbp->lgre, 6.0 ); e_lg = -(twbp->lgcij/( r_ij6 + re6 )); total_EvdW += Tap * e_lg; de_lg = -6.0 * e_lg * r_ij5 / ( r_ij6 + re6 ) ; CEvd += dTap * e_lg + Tap * de_lg / r_ij; } } /*Coulomb Calculations*/ dr3gamij_1 = ( r_ij * r_ij * r_ij + twbp->gamma ); dr3gamij_3 = pow( dr3gamij_1 , 0.33333333333333 ); tmp = Tap / dr3gamij_3; total_Eele += e_ele = C_ele * system->my_atoms[i].q * system->my_atoms[j].q * tmp; CEclmb = C_ele * system->my_atoms[i].q * system->my_atoms[j].q * ( dTap - Tap * r_ij / dr3gamij_1 ) / dr3gamij_3; /* tally into per-atom energy */ if( system->pair_ptr->evflag || system->pair_ptr->vflag_atom) { pe_vdw = Tap * (e_vdW + e_core + e_lg); rvec_ScaledSum( delij, 1., system->my_atoms[i].x, -1., system->my_atoms[j].x ); f_tmp = -(CEvd + CEclmb); pair_reax_ptr->ev_tally_thr_proxy( system->pair_ptr, i, j, natoms, 1, pe_vdw, e_ele, f_tmp, delij[0], delij[1], delij[2], thr); } if( control->virial == 0 ) { rvec_ScaledAdd( workspace->f[i], -(CEvd + CEclmb), nbr_pj->dvec ); rvec_ScaledAdd( workspace->forceReduction[reductionOffset+j], +(CEvd + CEclmb), nbr_pj->dvec ); } else { /* NPT, iNPT or sNPT */ /* for pressure coupling, terms not related to bond order derivatives are added directly into pressure vector/tensor */ rvec_Scale( temp, CEvd + CEclmb, nbr_pj->dvec ); rvec_ScaledAdd( workspace->f[reductionOffset+i], -1., temp ); rvec_Add( workspace->forceReduction[reductionOffset+j], temp); rvec_iMultiply( ext_press, nbr_pj->rel_box, temp ); rvec_Add( workspace->my_ext_pressReduction[tid], ext_press ); } } } } pair_reax_ptr->reduce_thr_proxy(system->pair_ptr, system->pair_ptr->eflag_either, system->pair_ptr->vflag_either, thr); } // parallel region data->my_en.e_vdW = total_EvdW; data->my_en.e_ele = total_Eele; Compute_Polarization_Energy( system, data ); } /* ---------------------------------------------------------------------- */ void Tabulated_vdW_Coulomb_Energy_OMP(reax_system *system,control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control ) { double SMALL = 0.0001; int natoms = system->n; reax_list *far_nbrs = (*lists) + FAR_NBRS; - int nthreads = control->nthreads; - long totalReductionSize = system->N * nthreads; double total_EvdW = 0.; double total_Eele = 0.; #if defined(_OPENMP) #pragma omp parallel default(shared) reduction(+:total_EvdW, total_Eele) #endif { int i, j, pj, r; int type_i, type_j, tmin, tmax; int start_i, end_i, orig_i, orig_j, flag; double r_ij, base, dif; double e_vdW, e_ele; double CEvd, CEclmb; double f_tmp, delij[3]; rvec temp, ext_press; far_neighbor_data *nbr_pj; LR_lookup_table *t; #if defined(_OPENMP) int tid = omp_get_thread_num(); #else int tid = 0; #endif long froffset = (system->N * tid); class PairReaxCOMP *pair_reax_ptr; pair_reax_ptr = static_cast(system->pair_ptr); class ThrData *thr = pair_reax_ptr->getFixOMP()->get_thr(tid); pair_reax_ptr->ev_setup_thr_proxy(system->pair_ptr->eflag_either, system->pair_ptr->vflag_either, natoms, system->pair_ptr->eatom, system->pair_ptr->vatom, thr); #if defined(_OPENMP) #pragma omp for schedule(guided) #endif for (i = 0; i < natoms; ++i) { type_i = system->my_atoms[i].type; if(type_i < 0) continue; start_i = Start_Index(i,far_nbrs); end_i = End_Index(i,far_nbrs); orig_i = system->my_atoms[i].orig_id; for (pj = start_i; pj < end_i; ++pj) { nbr_pj = &(far_nbrs->select.far_nbr_list[pj]); j = nbr_pj->nbr; type_j = system->my_atoms[j].type; if(type_j < 0) continue; orig_j = system->my_atoms[j].orig_id; flag = 0; if(nbr_pj->d <= control->nonb_cut) { if(j < natoms) flag = 1; else if (orig_i < orig_j) flag = 1; else if (orig_i == orig_j) { if (nbr_pj->dvec[2] > SMALL) flag = 1; else if (fabs(nbr_pj->dvec[2]) < SMALL) { if (nbr_pj->dvec[1] > SMALL) flag = 1; else if (fabs(nbr_pj->dvec[1]) < SMALL && nbr_pj->dvec[0] > SMALL) flag = 1; } } } if (flag) { r_ij = nbr_pj->d; tmin = MIN( type_i, type_j ); tmax = MAX( type_i, type_j ); t = &( LR[tmin][tmax] ); /* Cubic Spline Interpolation */ r = (int)(r_ij * t->inv_dx); if( r == 0 ) ++r; base = (double)(r+1) * t->dx; dif = r_ij - base; e_vdW = ((t->vdW[r].d*dif + t->vdW[r].c)*dif + t->vdW[r].b)*dif + t->vdW[r].a; e_ele = ((t->ele[r].d*dif + t->ele[r].c)*dif + t->ele[r].b)*dif + t->ele[r].a; e_ele *= system->my_atoms[i].q * system->my_atoms[j].q; total_EvdW += e_vdW; total_Eele += e_ele; CEvd = ((t->CEvd[r].d*dif + t->CEvd[r].c)*dif + t->CEvd[r].b)*dif + t->CEvd[r].a; CEclmb = ((t->CEclmb[r].d*dif+t->CEclmb[r].c)*dif+t->CEclmb[r].b)*dif + t->CEclmb[r].a; CEclmb *= system->my_atoms[i].q * system->my_atoms[j].q; /* tally into per-atom energy */ if( system->pair_ptr->evflag || system->pair_ptr->vflag_atom) { rvec_ScaledSum( delij, 1., system->my_atoms[i].x, -1., system->my_atoms[j].x ); f_tmp = -(CEvd + CEclmb); pair_reax_ptr->ev_tally_thr_proxy(system->pair_ptr, i, j, natoms, 1, e_vdW, e_ele, f_tmp, delij[0], delij[1], delij[2], thr); } if( control->virial == 0 ) { rvec_ScaledAdd( workspace->f[i], -(CEvd + CEclmb), nbr_pj->dvec ); rvec_ScaledAdd( workspace->forceReduction[froffset+j], +(CEvd + CEclmb), nbr_pj->dvec ); } else { // NPT, iNPT or sNPT /* for pressure coupling, terms not related to bond order derivatives are added directly into pressure vector/tensor */ rvec_Scale( temp, CEvd + CEclmb, nbr_pj->dvec ); rvec_ScaledAdd( workspace->f[i], -1., temp ); rvec_Add( workspace->forceReduction[froffset+j], temp ); rvec_iMultiply( ext_press, nbr_pj->rel_box, temp ); rvec_Add( workspace->my_ext_pressReduction[tid], ext_press ); } } } } pair_reax_ptr->reduce_thr_proxy(system->pair_ptr, system->pair_ptr->eflag_either, system->pair_ptr->vflag_either, thr); } // end omp parallel data->my_en.e_vdW = total_EvdW; data->my_en.e_ele = total_Eele; Compute_Polarization_Energy( system, data ); } diff --git a/src/USER-QTB/fix_qbmsst.h b/src/USER-QTB/fix_qbmsst.h index 3484076ab..cec54e40d 100644 --- a/src/USER-QTB/fix_qbmsst.h +++ b/src/USER-QTB/fix_qbmsst.h @@ -1,124 +1,124 @@ -/* ---------------------------------------------------------------------- +/* -*- 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 authors: Shen,Yuan, Qi,Tingting, and Reed,Evan Implementation of the Multi-Scale Shock Method with quantum nuclear effects ------------------------------------------------------------------------- */ #ifdef FIX_CLASS FixStyle(qbmsst,FixQBMSST) #else #ifndef FIX_QBMSST_H #define FIX_QBMSST_H #include "fix.h" namespace LAMMPS_NS { class FixQBMSST : public Fix { public: FixQBMSST(class LAMMPS *, int, char **); ~FixQBMSST(); int setmask(); void init(); void setup(int); void initial_integrate(int); void final_integrate(); double compute_scalar(); double compute_vector(int); void write_restart(FILE *); void restart(char *); int modify_param(int, char **); double memory_usage(); void grow_arrays(int); void copy_arrays(int, int, int); int pack_exchange(int, double *); int unpack_exchange(int, double *); private: // msst parameters int direction; // Direction of shock double velocity; // Velocity of the shock double qmass; // Effective cell mass double mu; // Effective cell viscosity double e0; // Initial energy double v0; // Initial volume double p0; // Initial pressure int p0_set; // Is pressure set int v0_set; // Is volume set int e0_set; // Is energy set double tscale; // Converts thermal energy to compressive strain ke at simulation start char *id_temp,*id_press, *id_pe; // Strings with identifiers of created computes. int tflag,pflag,vsflag,peflag; // Flags to keep track of computes that were created. double dtv; // update->dt double dtf; // Full step size double dthalf; // half step size bigint ntotal; // atom->natoms double boltz,nktv2p, mvv2e; // Boltzmann factor and unit conversions class Compute *temperature; // Computes created to evaluate class Compute *pressure; // thermodynamic quantities. class Compute *pe; double **old_velocity; // Saved velocities. int atoms_allocated; // size of old_velocity double dilation[3]; double omega[3]; // Time derivative of the volume. double total_mass; // Mass of the computational cell int kspace_flag; // 1 if KSpace invoked, 0 if not int nrigid; // number of rigid fixes int *rfix; // indices of rigid fixes double p_current[3]; // pressure double velocity_sum; // Sum of the velocities squared. double lagrangian_position; // Lagrangian location of computational cell // qbmsst parameters double t_period, fric_coef; // friction coefficient int seed; // seed for the random number generator double f_max; // frequency cutoff int N_f; // number of frequency grid double eta; // coupling coefficient between shock and the qtb int beta; // average beta steps before updating the qtb temperature double t_init; // initial qtb temperature int qtb_set; // 1 if its a restarting qbmsst, 0 if not int counter_l, counter_mu; // counter l and mu double t_current; // qtb temperature double h_timestep; // time step to update the random forces int alpha; // number of time steps to update the random forces class RanMars *random; // random number generator double *gfactor; // factors of random forces double *omega_H,*time_H; // H gives the desired power spectrum double **random_array_0, **random_array_1, **random_array_2; // random number arrays give independence between atoms and directions double **fran; // random forces double old_eavg; // average previous energies // functions void couple(); void remap(int); void check_alloc(int n); double compute_etotal(); double compute_egrand(); double compute_vol(); double compute_vsum(); double compute_hugoniot(); double compute_rayleigh(); double compute_lagrangian_speed(); double compute_lagrangian_position(); }; } #endif #endif diff --git a/src/USER-QTB/fix_qtb.h b/src/USER-QTB/fix_qtb.h index e2b763453..5537ecb56 100644 --- a/src/USER-QTB/fix_qtb.h +++ b/src/USER-QTB/fix_qtb.h @@ -1,71 +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. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing authors: Shen,Yuan, Qi,Tingting, and Reed,Evan Implementation of the colored thermostat for quantum nuclear effects ------------------------------------------------------------------------- */ #ifdef FIX_CLASS FixStyle(qtb,FixQTB) #else #ifndef LMP_FIX_QTB_H #define LMP_FIX_QTB_H #include "fix.h" namespace LAMMPS_NS { class FixQTB : public Fix { public: FixQTB(class LAMMPS *, int, char **); virtual ~FixQTB(); int setmask(); void init(); void setup(int); void post_force(int); void post_force_respa(int, int, int); int modify_param(int, char **); double memory_usage(); void grow_arrays(int); void copy_arrays(int, int, int); int pack_exchange(int, double *); int unpack_exchange(int, double *); private: // qtb parameters int counter_mu; // counter l and mu double t_period, fric_coef; // friction coefficient int seed; // seed for the random number generator double f_max; // frequency cutoff int N_f; // number of frequency grid double t_target; // target qtb temperature char *id_temp; class Compute *temperature; double h_timestep; // time step to update the random forces int alpha; // number of time steps to update the random forces class RanMars *random; // random number generator double *gfactor1,*gfactor3; // factors of frictions and random forces double *omega_H,*time_H; // H gives the desired power spectrum double **random_array_0, **random_array_1, **random_array_2; // random number arrays give independence between atoms and directions int nlevels_respa; double **fran, fsum[3], fsumall[3]; // random forces and their sums }; } #endif #endif diff --git a/src/USER-QUIP/pair_quip.h b/src/USER-QUIP/pair_quip.h index 15e143aee..f86df015e 100644 --- a/src/USER-QUIP/pair_quip.h +++ b/src/USER-QUIP/pair_quip.h @@ -1,64 +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 PAIR_CLASS PairStyle(quip,PairQUIP) #else #ifndef LMP_PAIR_QUIP_H #define LMP_PAIR_QUIP_H #include "pair.h" extern "C" { void quip_lammps_wrapper(int*, int*, int*, int*, int*, int*, int*, int*, double*, int*, int*, double*, double*, double*, double*, double*, double*); void quip_lammps_potential_initialise(int*, int*, double*, char*, int*, char*, int*); } namespace LAMMPS_NS { class PairQUIP : public Pair { public: PairQUIP(class LAMMPS *); ~PairQUIP(); void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); double init_one(int, int); void allocate(); private: double cutoff; int* quip_potential; int n_quip_potential; int *map; // mapping from atom types to elements char *quip_file; // mapping from atom types to elements int n_quip_file; char *quip_string; // mapping from atom types to elements int n_quip_string; }; } #endif #endif diff --git a/src/USER-REAXC/fix_reaxc_species.cpp b/src/USER-REAXC/fix_reaxc_species.cpp index df28a34fe..62b3bff93 100644 --- a/src/USER-REAXC/fix_reaxc_species.cpp +++ b/src/USER-REAXC/fix_reaxc_species.cpp @@ -1,993 +1,991 @@ /* ---------------------------------------------------------------------- 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: Ray Shan (Sandia, tnshan@sandia.gov) Oleg Sergeev (VNIIA, sergeev@vniia.ru) ------------------------------------------------------------------------- */ #include #include #include "atom.h" #include #include "fix_ave_atom.h" #include "fix_reaxc_species.h" #include "domain.h" #include "update.h" #include "pair_reaxc.h" #include "modify.h" #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" #include "comm.h" #include "force.h" #include "compute.h" #include "input.h" #include "variable.h" #include "memory.h" #include "error.h" #include "reaxc_list.h" using namespace LAMMPS_NS; using namespace FixConst; /* ---------------------------------------------------------------------- */ FixReaxCSpecies::FixReaxCSpecies(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { if (narg < 7) error->all(FLERR,"Illegal fix reax/c/species command"); force_reneighbor = 0; vector_flag = 1; size_vector = 2; extvector = 0; peratom_flag = 1; size_peratom_cols = 0; peratom_freq = 1; nvalid = -1; MPI_Comm_rank(world,&me); MPI_Comm_size(world,&nprocs); ntypes = atom->ntypes; nevery = atoi(arg[3]); nrepeat = atoi(arg[4]); global_freq = nfreq = atoi(arg[5]); comm_forward = 4; if (nevery <= 0 || nrepeat <= 0 || nfreq <= 0) error->all(FLERR,"Illegal fix reax/c/species command"); if (nfreq % nevery || nrepeat*nevery > nfreq) error->all(FLERR,"Illegal fix reax/c/species command"); // Neighbor lists must stay unchanged during averaging of bonds, // but may be updated when no averaging is performed. int rene_flag = 0; if (nevery * nrepeat != 1 && (nfreq % neighbor->every != 0 || neighbor->every < nevery * nrepeat)) { int newneighborevery = nevery * nrepeat; while (nfreq % newneighborevery != 0 && newneighborevery <= nfreq / 2) newneighborevery++; if (nfreq % newneighborevery != 0) newneighborevery = nfreq; neighbor->every = newneighborevery; rene_flag = 1; } if (nevery * nrepeat != 1 && (neighbor->delay != 0 || neighbor->dist_check != 0)) { neighbor->delay = 0; neighbor->dist_check = 0; rene_flag = 1; } if (me == 0 && rene_flag) { char str[128]; sprintf(str,"Resetting reneighboring criteria for fix reax/c/species"); error->warning(FLERR,str); } tmparg = NULL; memory->create(tmparg,4,4,"reax/c/species:tmparg"); strcpy(tmparg[0],arg[3]); strcpy(tmparg[1],arg[4]); strcpy(tmparg[2],arg[5]); if (me == 0) { char *suffix = strrchr(arg[6],'.'); if (suffix && strcmp(suffix,".gz") == 0) { #ifdef LAMMPS_GZIP char gzip[128]; sprintf(gzip,"gzip -6 > %s",arg[6]); #ifdef _WIN32 fp = _popen(gzip,"wb"); #else fp = popen(gzip,"w"); #endif #else error->one(FLERR,"Cannot open gzipped file"); #endif } else fp = fopen(arg[6],"w"); if (fp == NULL) { char str[128]; sprintf(str,"Cannot open fix reax/c/species file %s",arg[6]); error->one(FLERR,str); } } x0 = NULL; clusterID = NULL; int ntmp = 1; memory->create(x0,ntmp,"reax/c/species:x0"); memory->create(clusterID,ntmp,"reax/c/species:clusterID"); vector_atom = clusterID; BOCut = NULL; Name = NULL; MolName = NULL; MolType = NULL; NMol = NULL; nd = NULL; molmap = NULL; nmax = 0; setupflag = 0; // set default bond order cutoff int n, i, j, itype, jtype; double bo_cut; bg_cut = 0.30; n = ntypes+1; memory->create(BOCut,n,n,"reax/c/species:BOCut"); for (i = 1; i < n; i ++) for (j = 1; j < n; j ++) BOCut[i][j] = bg_cut; // optional args eletype = NULL; ele = filepos = NULL; eleflag = posflag = padflag = 0; singlepos_opened = multipos_opened = 0; multipos = 0; posfreq = 0; int iarg = 7; while (iarg < narg) { // set BO cutoff if (strcmp(arg[iarg],"cutoff") == 0) { if (iarg+4 > narg) error->all(FLERR,"Illegal fix reax/c/species command"); itype = atoi(arg[iarg+1]); jtype = atoi(arg[iarg+2]); bo_cut = atof(arg[iarg+3]); if (itype > ntypes || jtype > ntypes) error->all(FLERR,"Illegal fix reax/c/species command"); if (itype <= 0 || jtype <= 0) error->all(FLERR,"Illegal fix reax/c/species command"); if (bo_cut > 1.0 || bo_cut < 0.0) error->all(FLERR,"Illegal fix reax/c/species command"); BOCut[itype][jtype] = bo_cut; BOCut[jtype][itype] = bo_cut; iarg += 4; // modify element type names } else if (strcmp(arg[iarg],"element") == 0) { if (iarg+ntypes+1 > narg) error->all(FLERR,"Illegal fix reax/c/species command"); eletype = (char**) malloc(ntypes*sizeof(char*)); for (int i = 0; i < ntypes; i ++) { eletype[i] = (char*) malloc(2*sizeof(char)); strcpy(eletype[i],arg[iarg+1+i]); } eleflag = 1; iarg += ntypes + 1; // position of molecules } else if (strcmp(arg[iarg],"position") == 0) { if (iarg+3 > narg) error->all(FLERR,"Illegal fix reax/c/species command"); posflag = 1; posfreq = atoi(arg[iarg+1]); if (posfreq < nfreq || (posfreq%nfreq != 0)) error->all(FLERR,"Illegal fix reax/c/species command"); filepos = new char[255]; strcpy(filepos,arg[iarg+2]); if (strchr(filepos,'*')) { multipos = 1; } else { if (me == 0) { pos = fopen(filepos, "w"); if (pos == NULL) error->one(FLERR,"Cannot open fix reax/c/species position file"); } singlepos_opened = 1; multipos = 0; } iarg += 3; } else error->all(FLERR,"Illegal fix reax/c/species command"); } if (!eleflag) { memory->create(ele,ntypes+1,"reax/c/species:ele"); ele[0]='C'; if (ntypes > 1) ele[1]='H'; if (ntypes > 2) ele[2]='O'; if (ntypes > 3) ele[3]='N'; } vector_nmole = 0; vector_nspec = 0; } /* ---------------------------------------------------------------------- */ FixReaxCSpecies::~FixReaxCSpecies() { memory->destroy(ele); memory->destroy(BOCut); memory->destroy(clusterID); memory->destroy(x0); memory->destroy(nd); memory->destroy(Name); memory->destroy(NMol); memory->destroy(MolType); memory->destroy(MolName); memory->destroy(tmparg); if (filepos) delete [] filepos; if (me == 0) fclose(fp); if (me == 0 && posflag && multipos_opened) fclose(pos); modify->delete_compute("SPECATOM"); modify->delete_fix("SPECBOND"); } /* ---------------------------------------------------------------------- */ int FixReaxCSpecies::setmask() { int mask = 0; mask |= POST_INTEGRATE; return mask; } /* ---------------------------------------------------------------------- */ void FixReaxCSpecies::setup(int vflag) { ntotal = static_cast (atom->natoms); if (Name == NULL) memory->create(Name,ntypes,"reax/c/species:Name"); post_integrate(); } /* ---------------------------------------------------------------------- */ void FixReaxCSpecies::init() { if (atom->tag_enable == 0) error->all(FLERR,"Cannot use fix reax/c/species unless atoms have IDs"); reaxc = (PairReaxC *) force->pair_match("reax/c",0); if (reaxc == NULL) error->all(FLERR,"Cannot use fix reax/c/species without " "pair_style reax/c, reax/c/kk, or reax/c/omp"); reaxc->fixspecies_flag = 1; // reset next output timestep if not yet set or timestep has been reset if (nvalid != update->ntimestep) nvalid = update->ntimestep+nfreq; // check if this fix has been called twice int count = 0; for (int i = 0; i < modify->nfix; i++) if (strcmp(modify->fix[i]->style,"reax/c/species") == 0) count++; if (count > 1 && comm->me == 0) error->warning(FLERR,"More than one fix reax/c/species"); if (!setupflag) { // create a compute to store properties create_compute(); // create a fix to point to fix_ave_atom for averaging stored properties create_fix(); setupflag = 1; } } /* ---------------------------------------------------------------------- */ void FixReaxCSpecies::create_compute() { int narg; char **args; narg = 34; args = new char*[narg]; args[0] = (char *) "SPECATOM"; args[1] = (char *) "all"; args[2] = (char *) "SPEC/ATOM"; args[3] = (char *) "q"; args[4] = (char *) "x"; args[5] = (char *) "y"; args[6] = (char *) "z"; args[7] = (char *) "vx"; args[8] = (char *) "vy"; args[9] = (char *) "vz"; args[10] = (char *) "abo01"; args[11] = (char *) "abo02"; args[12] = (char *) "abo03"; args[13] = (char *) "abo04"; args[14] = (char *) "abo05"; args[15] = (char *) "abo06"; args[16] = (char *) "abo07"; args[17] = (char *) "abo08"; args[18] = (char *) "abo09"; args[19] = (char *) "abo10"; args[20] = (char *) "abo11"; args[21] = (char *) "abo12"; args[22] = (char *) "abo13"; args[23] = (char *) "abo14"; args[24] = (char *) "abo15"; args[25] = (char *) "abo16"; args[26] = (char *) "abo17"; args[27] = (char *) "abo18"; args[28] = (char *) "abo19"; args[29] = (char *) "abo20"; args[30] = (char *) "abo21"; args[31] = (char *) "abo22"; args[32] = (char *) "abo23"; args[33] = (char *) "abo24"; modify->add_compute(narg,args); delete [] args; } /* ---------------------------------------------------------------------- */ void FixReaxCSpecies::create_fix() { int narg; char **args; narg = 37; args = new char*[narg]; args[0] = (char *) "SPECBOND"; args[1] = (char *) "all"; args[2] = (char *) "ave/atom"; args[3] = tmparg[0]; args[4] = tmparg[1]; args[5] = tmparg[2]; args[6] = (char *) "c_SPECATOM[1]"; // q, array_atoms[i][0] args[7] = (char *) "c_SPECATOM[2]"; // x, 1 args[8] = (char *) "c_SPECATOM[3]"; // y, 2 args[9] = (char *) "c_SPECATOM[4]"; // z, 3 args[10] = (char *) "c_SPECATOM[5]"; // vx, 4 args[11] = (char *) "c_SPECATOM[6]"; // vy, 5 args[12] = (char *) "c_SPECATOM[7]"; // vz, 6 args[13] = (char *) "c_SPECATOM[8]"; // abo01, 7 args[14] = (char *) "c_SPECATOM[9]"; args[15] = (char *) "c_SPECATOM[10]"; args[16] = (char *) "c_SPECATOM[11]"; args[17] = (char *) "c_SPECATOM[12]"; args[18] = (char *) "c_SPECATOM[13]"; args[19] = (char *) "c_SPECATOM[14]"; args[20] = (char *) "c_SPECATOM[15]"; args[21] = (char *) "c_SPECATOM[16]"; args[22] = (char *) "c_SPECATOM[17]"; args[23] = (char *) "c_SPECATOM[18]"; args[24] = (char *) "c_SPECATOM[19]"; // abo12, 18 args[25] = (char *) "c_SPECATOM[20]"; args[26] = (char *) "c_SPECATOM[21]"; args[27] = (char *) "c_SPECATOM[22]"; args[28] = (char *) "c_SPECATOM[23]"; args[29] = (char *) "c_SPECATOM[24]"; args[30] = (char *) "c_SPECATOM[25]"; args[31] = (char *) "c_SPECATOM[26]"; args[32] = (char *) "c_SPECATOM[27]"; args[33] = (char *) "c_SPECATOM[28]"; args[34] = (char *) "c_SPECATOM[29]"; args[35] = (char *) "c_SPECATOM[30]"; args[36] = (char *) "c_SPECATOM[31]"; modify->add_fix(narg,args); f_SPECBOND = (FixAveAtom *) modify->fix[modify->nfix-1]; delete [] args; } /* ---------------------------------------------------------------------- */ void FixReaxCSpecies::init_list(int id, NeighList *ptr) { list = ptr; } /* ---------------------------------------------------------------------- */ void FixReaxCSpecies::post_integrate() { Output_ReaxC_Bonds(update->ntimestep,fp); if (me == 0) fflush(fp); } /* ---------------------------------------------------------------------- */ void FixReaxCSpecies::Output_ReaxC_Bonds(bigint ntimestep, FILE *fp) { int Nmole, Nspec; // point to fix_ave_atom f_SPECBOND->end_of_step(); if (ntimestep != nvalid) return; nlocal = atom->nlocal; if (atom->nmax > nmax) { nmax = atom->nmax; memory->destroy(x0); memory->destroy(clusterID); memory->create(x0,nmax,"reax/c/species:x0"); memory->create(clusterID,nmax,"reax/c/species:clusterID"); vector_atom = clusterID; } for (int i = 0; i < nmax; i++) { x0[i].x = x0[i].y = x0[i].z = 0.0; } Nmole = Nspec = 0; FindMolecule(); SortMolecule (Nmole); FindSpecies(Nmole, Nspec); vector_nmole = Nmole; vector_nspec = Nspec; if (me == 0 && ntimestep >= 0) WriteFormulas (Nmole, Nspec); if (posflag && ((ntimestep)%posfreq==0)) { WritePos(Nmole, Nspec); if (me == 0) fflush(pos); } nvalid += nfreq; } /* ---------------------------------------------------------------------- */ AtomCoord FixReaxCSpecies::chAnchor(AtomCoord in1, AtomCoord in2) { if (in1.x < in2.x) return in1; else if (in1.x == in2.x) { if (in1.y < in2.y) return in1; else if (in1.y == in2.y) { if (in1.z < in2.z) return in1; } } return in2; } /* ---------------------------------------------------------------------- */ void FixReaxCSpecies::FindMolecule () { int i,j,ii,jj,inum,itype,jtype,loop,looptot; int change,done,anychange; int *mask = atom->mask; int *ilist; double bo_tmp,bo_cut; double **spec_atom = f_SPECBOND->array_atom; - const double * const * const x = atom->x; - const int nlocal = atom->nlocal; inum = reaxc->list->inum; ilist = reaxc->list->ilist; for (ii = 0; ii < inum; ii++) { i = ilist[ii]; if (mask[i] & groupbit) { clusterID[i] = atom->tag[i]; x0[i].x = spec_atom[i][1]; x0[i].y = spec_atom[i][2]; x0[i].z = spec_atom[i][3]; } else clusterID[i] = 0.0; } loop = 0; while (1) { comm->forward_comm_fix(this); loop ++; change = 0; while (1) { done = 1; for (ii = 0; ii < inum; ii++) { i = ilist[ii]; if (!(mask[i] & groupbit)) continue; itype = atom->type[i]; for (jj = 0; jj < MAXSPECBOND; jj++) { j = reaxc->tmpid[i][jj]; if ((j == 0) || (j < i)) continue; if (!(mask[j] & groupbit)) continue; if (clusterID[i] == clusterID[j] && x0[i].x == x0[j].x && x0[i].y == x0[j].y && x0[i].z == x0[j].z) continue; jtype = atom->type[j]; bo_cut = BOCut[itype][jtype]; bo_tmp = spec_atom[i][jj+7]; if (bo_tmp > bo_cut) { clusterID[i] = clusterID[j] = MIN(clusterID[i], clusterID[j]); x0[i] = x0[j] = chAnchor(x0[i], x0[j]); done = 0; } } } if (!done) change = 1; if (done) break; } MPI_Allreduce(&change,&anychange,1,MPI_INT,MPI_MAX,world); if (!anychange) break; MPI_Allreduce(&loop,&looptot,1,MPI_INT,MPI_SUM,world); if (looptot >= 400*nprocs) break; } } /* ---------------------------------------------------------------------- */ void FixReaxCSpecies::SortMolecule(int &Nmole) { memory->destroy(molmap); molmap = NULL; int n, idlo, idhi; int *mask =atom->mask; int lo = ntotal; int hi = -ntotal; int flag = 0; for (n = 0; n < nlocal; n++) { if (!(mask[n] & groupbit)) continue; if (clusterID[n] == 0.0) flag = 1; lo = MIN(lo,nint(clusterID[n])); hi = MAX(hi,nint(clusterID[n])); } int flagall; MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); if (flagall && me == 0) error->warning(FLERR,"Atom with cluster ID = 0 included in " "fix reax/c/species group"); MPI_Allreduce(&lo,&idlo,1,MPI_INT,MPI_MIN,world); MPI_Allreduce(&hi,&idhi,1,MPI_INT,MPI_MAX,world); if (idlo == ntotal) if (me == 0) error->warning(FLERR,"Atom with cluster ID = maxmol " "included in fix reax/c/species group"); int nlen = idhi - idlo + 1; memory->create(molmap,nlen,"reax/c/species:molmap"); for (n = 0; n < nlen; n++) molmap[n] = 0; for (n = 0; n < nlocal; n++) { if (!(mask[n] & groupbit)) continue; molmap[nint(clusterID[n])-idlo] = 1; } int *molmapall; memory->create(molmapall,nlen,"reax/c/species:molmapall"); MPI_Allreduce(molmap,molmapall,nlen,MPI_INT,MPI_MAX,world); Nmole = 0; for (n = 0; n < nlen; n++) { if (molmapall[n]) molmap[n] = Nmole++; else molmap[n] = -1; } memory->destroy(molmapall); flag = 0; for (n = 0; n < nlocal; n++) { if (mask[n] & groupbit) continue; if (nint(clusterID[n]) < idlo || nint(clusterID[n]) > idhi) continue; if (molmap[nint(clusterID[n])-idlo] >= 0) flag = 1; } MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); if (flagall && comm->me == 0) error->warning(FLERR,"One or more cluster has atoms not in group"); for (n = 0; n < nlocal; n++) { if (!(mask[n] & groupbit)) continue; clusterID[n] = molmap[nint(clusterID[n])-idlo] + 1; } memory->destroy(molmap); molmap = NULL; } /* ---------------------------------------------------------------------- */ void FixReaxCSpecies::FindSpecies(int Nmole, int &Nspec) { int k, l, m, n, itype, cid; int flag_identity, flag_mol, flag_spec; int flag_tmp; int *mask =atom->mask; int *Nameall, *NMolall; memory->destroy(MolName); MolName = NULL; memory->create(MolName,Nmole*(ntypes+1),"reax/c/species:MolName"); memory->destroy(NMol); NMol = NULL; memory->create(NMol,Nmole,"reax/c/species:NMol"); for (m = 0; m < Nmole; m ++) NMol[m] = 1; memory->create(Nameall,ntypes,"reax/c/species:Nameall"); memory->create(NMolall,Nmole,"reax/c/species:NMolall"); for (m = 1, Nspec = 0; m <= Nmole; m ++) { for (n = 0; n < ntypes; n ++) Name[n] = 0; for (n = 0, flag_mol = 0; n < nlocal; n ++) { if (!(mask[n] & groupbit)) continue; cid = nint(clusterID[n]); if (cid == m) { itype = atom->type[n]-1; Name[itype] ++; flag_mol = 1; } } MPI_Allreduce(&flag_mol,&flag_tmp,1,MPI_INT,MPI_MAX,world); flag_mol = flag_tmp; MPI_Allreduce(Name,Nameall,ntypes,MPI_INT,MPI_SUM,world); for (n = 0; n < ntypes; n++) Name[n] = Nameall[n]; if (flag_mol == 1) { flag_identity = 1; for (k = 0; k < Nspec; k ++) { flag_spec=0; for (l = 0; l < ntypes; l ++) if (MolName[ntypes*k+l] != Name[l]) flag_spec = 1; if (flag_spec == 0) NMol[k] ++; flag_identity *= flag_spec; } if (Nspec == 0 || flag_identity == 1) { for (l = 0; l < ntypes; l ++) MolName[ntypes*Nspec+l] = Name[l]; Nspec ++; } } } memory->destroy(NMolall); memory->destroy(Nameall); memory->destroy(nd); nd = NULL; memory->create(nd,Nspec,"reax/c/species:nd"); memory->destroy(MolType); MolType = NULL; memory->create(MolType,Nspec*(ntypes+2),"reax/c/species:MolType"); } /* ---------------------------------------------------------------------- */ int FixReaxCSpecies::CheckExistence(int id, int ntypes) { int i, j, molid, flag; for (i = 0; i < Nmoltype; i ++) { flag = 0; for (j = 0; j < ntypes; j ++) { molid = MolType[ntypes * i + j]; if (molid != MolName[ntypes * id + j]) flag = 1; } if (flag == 0) return i; } for (i = 0; i < ntypes; i ++) MolType[ntypes * Nmoltype + i] = MolName[ntypes *id + i]; Nmoltype ++; return Nmoltype - 1; } /* ---------------------------------------------------------------------- */ void FixReaxCSpecies::WriteFormulas(int Nmole, int Nspec) { int i, j, itemp; bigint ntimestep = update->ntimestep; fprintf(fp,"# Timestep No_Moles No_Specs "); Nmoltype = 0; for (i = 0; i < Nspec; i ++) nd[i] = CheckExistence(i, ntypes); for (i = 0; i < Nmoltype; i ++) { for (j = 0;j < ntypes; j ++) { itemp = MolType[ntypes * i + j]; if (itemp != 0) { if (eletype) fprintf(fp,"%s",eletype[j]); else fprintf(fp,"%c",ele[j]); if (itemp != 1) fprintf(fp,"%d",itemp); } } fprintf(fp,"\t"); } fprintf(fp,"\n"); fprintf(fp,BIGINT_FORMAT,ntimestep); fprintf(fp,"%11d%11d\t",Nmole,Nspec); for (i = 0; i < Nmoltype; i ++) fprintf(fp," %d\t",NMol[i]); fprintf(fp,"\n"); } /* ---------------------------------------------------------------------- */ void FixReaxCSpecies::OpenPos() { char *filecurrent; bigint ntimestep = update->ntimestep; filecurrent = (char*) malloc((strlen(filepos)+16)*sizeof(char)); char *ptr = strchr(filepos,'*'); *ptr = '\0'; if (padflag == 0) sprintf(filecurrent,"%s" BIGINT_FORMAT "%s", filepos,ntimestep,ptr+1); else { char bif[8],pad[16]; strcpy(bif,BIGINT_FORMAT); sprintf(pad,"%%s%%0%d%s%%s",padflag,&bif[1]); sprintf(filecurrent,pad,filepos,ntimestep,ptr+1); } *ptr = '*'; if (me == 0) { pos = fopen(filecurrent, "w"); if (pos == NULL) error->one(FLERR,"Cannot open fix reax/c/species position file"); } else pos = NULL; multipos_opened = 1; free(filecurrent); } /* ---------------------------------------------------------------------- */ void FixReaxCSpecies::WritePos(int Nmole, int Nspec) { int i, itype, cid; int count, count_tmp, m, n, k; int *Nameall; int *mask =atom->mask; double avq, avq_tmp, avx[3], avx_tmp, box[3], halfbox[3]; double **spec_atom = f_SPECBOND->array_atom; if (multipos) OpenPos(); box[0] = domain->boxhi[0] - domain->boxlo[0]; box[1] = domain->boxhi[1] - domain->boxlo[1]; box[2] = domain->boxhi[2] - domain->boxlo[2]; for (int j = 0; j < 3; j++) halfbox[j] = box[j] / 2; if (me == 0) { fprintf(pos,"Timestep " BIGINT_FORMAT " NMole %d NSpec %d xlo %f " "xhi %f ylo %f yhi %f zlo %f zhi %f\n", update->ntimestep,Nmole, Nspec, domain->boxlo[0],domain->boxhi[0], domain->boxlo[1],domain->boxhi[1], domain->boxlo[2],domain->boxhi[2]); fprintf(pos,"ID\tAtom_Count\tType\tAve_q\t\tCoM_x\t\tCoM_y\t\tCoM_z\n"); } Nameall = NULL; memory->create(Nameall,ntypes,"reax/c/species:Nameall"); for (m = 1; m <= Nmole; m ++) { count = 0; avq = 0.0; for (n = 0; n < 3; n++) avx[n] = 0.0; for (n = 0; n < ntypes; n ++) Name[n] = 0; for (i = 0; i < nlocal; i ++) { if (!(mask[i] & groupbit)) continue; cid = nint(clusterID[i]); if (cid == m) { itype = atom->type[i]-1; Name[itype] ++; count ++; avq += spec_atom[i][0]; if ((x0[i].x - spec_atom[i][1]) > halfbox[0]) spec_atom[i][1] += box[0]; if ((spec_atom[i][1] - x0[i].x) > halfbox[0]) spec_atom[i][1] -= box[0]; if ((x0[i].y - spec_atom[i][2]) > halfbox[1]) spec_atom[i][2] += box[1]; if ((spec_atom[i][2] - x0[i].y) > halfbox[1]) spec_atom[i][2] -= box[1]; if ((x0[i].z - spec_atom[i][3]) > halfbox[2]) spec_atom[i][3] += box[2]; if ((spec_atom[i][3] - x0[i].z) > halfbox[2]) spec_atom[i][3] -= box[2]; for (n = 0; n < 3; n++) avx[n] += spec_atom[i][n+1]; } } avq_tmp = 0.0; MPI_Allreduce(&avq,&avq_tmp,1,MPI_DOUBLE,MPI_SUM,world); avq = avq_tmp; for (n = 0; n < 3; n++) { avx_tmp = 0.0; MPI_Reduce(&avx[n],&avx_tmp,1,MPI_DOUBLE,MPI_SUM,0,world); avx[n] = avx_tmp; } MPI_Reduce(&count,&count_tmp,1,MPI_INT,MPI_SUM,0,world); count = count_tmp; MPI_Reduce(Name,Nameall,ntypes,MPI_INT,MPI_SUM,0,world); for (n = 0; n < ntypes; n++) Name[n] = Nameall[n]; if (me == 0) { fprintf(pos,"%d\t%d\t",m,count); for (n = 0; n < ntypes; n++) { if (Name[n] != 0) { if (eletype) fprintf(pos,"%s",eletype[n]); else fprintf(pos,"%c",ele[n]); if (Name[n] != 1) fprintf(pos,"%d",Name[n]); } } if (count > 0) { avq /= count; for (k = 0; k < 3; k++) { avx[k] /= count; if (avx[k] >= domain->boxhi[k]) avx[k] -= box[k]; if (avx[k] < domain->boxlo[k]) avx[k] += box[k]; avx[k] -= domain->boxlo[k]; avx[k] /= box[k]; } fprintf(pos,"\t%.8f \t%.8f \t%.8f \t%.8f", avq,avx[0],avx[1],avx[2]); } fprintf(pos,"\n"); } } if (me == 0 && !multipos) fprintf(pos,"#\n"); memory->destroy(Nameall); } /* ---------------------------------------------------------------------- */ double FixReaxCSpecies::compute_vector(int n) { if (n == 0) return vector_nmole; if (n == 1) return vector_nspec; return 0.0; } /* ---------------------------------------------------------------------- */ int FixReaxCSpecies::nint(const double &r) { int i = 0; if (r>0.0) i = static_cast(r+0.5); else if (r<0.0) i = static_cast(r-0.5); return i; } /* ---------------------------------------------------------------------- */ int FixReaxCSpecies::pack_forward_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m] = clusterID[j]; buf[m+1] = x0[j].x; buf[m+2] = x0[j].y; buf[m+3] = x0[j].z; m += 4; } return m; } /* ---------------------------------------------------------------------- */ void FixReaxCSpecies::unpack_forward_comm(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) { clusterID[i] = buf[m]; x0[i].x = buf[m+1]; x0[i].y = buf[m+2]; x0[i].z = buf[m+3]; m += 4; } } /* ---------------------------------------------------------------------- */ double FixReaxCSpecies::memory_usage() { double bytes; bytes = 4*nmax*sizeof(double); // clusterID + x0 return bytes; } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-SMD/atom_vec_smd.h b/src/USER-SMD/atom_vec_smd.h index cea9a31f8..34fdfc1f7 100644 --- a/src/USER-SMD/atom_vec_smd.h +++ b/src/USER-SMD/atom_vec_smd.h @@ -1,125 +1,125 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 ATOM_CLASS AtomStyle(smd,AtomVecSMD) #else #ifndef LMP_ATOM_VEC_SMD_H #define LMP_ATOM_VEC_SMD_H #include "atom_vec.h" namespace LAMMPS_NS { class AtomVecSMD : public AtomVec { public: AtomVecSMD(class LAMMPS *); ~AtomVecSMD() {} void init(); void grow(int); void grow_reset(); void copy(int, int, int); void force_clear(int, size_t); int pack_comm(int, int *, double *, int, int *); int pack_comm_vel(int, int *, double *, int, int *); int pack_comm_hybrid(int, int *, double *); void unpack_comm(int, int, double *); void unpack_comm_vel(int, int, double *); int unpack_comm_hybrid(int, int, double *); int pack_reverse(int, int, double *); int pack_reverse_hybrid(int, int, double *); void unpack_reverse(int, int *, double *); int unpack_reverse_hybrid(int, int *, double *); int pack_border(int, int *, double *, int, int *); int pack_border_vel(int, int *, double *, int, int *); int pack_border_hybrid(int, int *, double *); void unpack_border(int, int, double *); void unpack_border_vel(int, int, double *); int unpack_border_hybrid(int, int, double *); int pack_exchange(int, double *); int unpack_exchange(double *); int size_restart(); int pack_restart(int, double *); int unpack_restart(double *); void create_atom(int, double *); void data_atom(double *, imageint, char **); int data_atom_hybrid(int, char **); void data_vel(int, char **); int data_vel_hybrid(int, char **); void pack_data(double **); int pack_data_hybrid(int, double *); void write_data(FILE *, int, double **); int write_data_hybrid(FILE *, double *); void pack_vel(double **); int pack_vel_hybrid(int, double *); void write_vel(FILE *, int, double **); int write_vel_hybrid(FILE *, double *); bigint memory_usage(); private: tagint *tag; int *type,*mask; imageint *image; double **x,**v,**f; double *radius,*rmass; tagint *molecule; double *vfrac,**x0,*contact_radius, **smd_data_9, *e, *de, **vest; double **tlsph_stress; double *eff_plastic_strain; double *damage; double *eff_plastic_strain_rate; }; } #endif #endif /* ERROR/WARNING messages: E: Per-processor system is too big The number of owned atoms plus ghost atoms on a single processor must fit in 32-bit integer. E: Invalid atom type in Atoms section of data file Atom types must range from 1 to specified # of types. E: Invalid radius in Atoms section of data file Radius must be >= 0.0. E: Invalid density in Atoms section of data file Density value cannot be <= 0.0. */ diff --git a/src/USER-SMD/compute_smd_contact_radius.h b/src/USER-SMD/compute_smd_contact_radius.h index 46034f2f1..f22dce1ba 100644 --- a/src/USER-SMD/compute_smd_contact_radius.h +++ b/src/USER-SMD/compute_smd_contact_radius.h @@ -1,55 +1,55 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/contact/radius,ComputeSMDContactRadius) #else #ifndef LMP_COMPUTE_SMD_CONTACT_RADIUS_H #define LMP_COMPUTE_SMD_CONTACT_RADIUS_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDContactRadius : public Compute { public: ComputeSMDContactRadius(class LAMMPS *, int, char **); ~ComputeSMDContactRadius(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double *contact_radius_vector; }; } #endif #endif diff --git a/src/USER-SMD/compute_smd_damage.h b/src/USER-SMD/compute_smd_damage.h index 1259788ec..c8447872c 100644 --- a/src/USER-SMD/compute_smd_damage.h +++ b/src/USER-SMD/compute_smd_damage.h @@ -1,55 +1,55 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/damage,ComputeSMDDamage) #else #ifndef LMP_COMPUTE_SMD_DAMAGE_H #define LMP_COMPUTE_SMD_DAMAGE_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDDamage : public Compute { public: ComputeSMDDamage(class LAMMPS *, int, char **); ~ComputeSMDDamage(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double *damage_vector; }; } #endif #endif diff --git a/src/USER-SMD/compute_smd_hourglass_error.h b/src/USER-SMD/compute_smd_hourglass_error.h index d4e39ce25..a6d1d1a1e 100644 --- a/src/USER-SMD/compute_smd_hourglass_error.h +++ b/src/USER-SMD/compute_smd_hourglass_error.h @@ -1,55 +1,55 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/hourglass/error,ComputeSMDHourglassError) #else #ifndef LMP_COMPUTE_SMD_HOURGLASS_ERROR_H #define LMP_COMPUTE_SMD_HOURGLASS_ERROR_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDHourglassError : public Compute { public: ComputeSMDHourglassError(class LAMMPS *, int, char **); ~ComputeSMDHourglassError(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double *hourglass_error_vector; }; } #endif #endif diff --git a/src/USER-SMD/compute_smd_internal_energy.h b/src/USER-SMD/compute_smd_internal_energy.h index 0754f6fe6..fbccfbfb7 100644 --- a/src/USER-SMD/compute_smd_internal_energy.h +++ b/src/USER-SMD/compute_smd_internal_energy.h @@ -1,55 +1,55 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/internal/energy,ComputeSMDInternalEnergy) #else #ifndef LMP_COMPUTE_SMD_INTERNAL_ENERGY_H #define LMP_COMPUTE_SMD_INTERNAL_ENERGY_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDInternalEnergy : public Compute { public: ComputeSMDInternalEnergy(class LAMMPS *, int, char **); ~ComputeSMDInternalEnergy(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double *internal_energy_vector; }; } #endif #endif diff --git a/src/USER-SMD/compute_smd_plastic_strain.h b/src/USER-SMD/compute_smd_plastic_strain.h index cdc322e4c..d2e64e31a 100644 --- a/src/USER-SMD/compute_smd_plastic_strain.h +++ b/src/USER-SMD/compute_smd_plastic_strain.h @@ -1,55 +1,55 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/plastic/strain,ComputeSMDPlasticStrain) #else #ifndef LMP_COMPUTE_SMD_PLASTIC_STRAIN_H #define LMP_COMPUTE_SMD_PLASTIC_STRAIN_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDPlasticStrain : public Compute { public: ComputeSMDPlasticStrain(class LAMMPS *, int, char **); ~ComputeSMDPlasticStrain(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double *plastic_strain_vector; }; } #endif #endif diff --git a/src/USER-SMD/compute_smd_plastic_strain_rate.h b/src/USER-SMD/compute_smd_plastic_strain_rate.h index efc4f0c67..03445e92f 100644 --- a/src/USER-SMD/compute_smd_plastic_strain_rate.h +++ b/src/USER-SMD/compute_smd_plastic_strain_rate.h @@ -1,55 +1,55 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/plastic/strain/rate,ComputeSMDPlasticStrainRate) #else #ifndef LMP_COMPUTE_SMD_PLASTIC_STRAIN_RATE_H #define LMP_COMPUTE_SMD_PLASTIC_STRAIN_RATE_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDPlasticStrainRate : public Compute { public: ComputeSMDPlasticStrainRate(class LAMMPS *, int, char **); ~ComputeSMDPlasticStrainRate(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double *plastic_strain_rate_vector; }; } #endif #endif diff --git a/src/USER-SMD/compute_smd_rho.h b/src/USER-SMD/compute_smd_rho.h index ce749c646..35dfdf8e9 100644 --- a/src/USER-SMD/compute_smd_rho.h +++ b/src/USER-SMD/compute_smd_rho.h @@ -1,55 +1,55 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/rho,ComputeSMDRho) #else #ifndef LMP_COMPUTE_SMD_RHO_H #define LMP_COMPUTE_SMD_RHO_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDRho : public Compute { public: ComputeSMDRho(class LAMMPS *, int, char **); ~ComputeSMDRho(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double *rhoVector; }; } #endif #endif diff --git a/src/USER-SMD/compute_smd_tlsph_defgrad.h b/src/USER-SMD/compute_smd_tlsph_defgrad.h index 654403e7a..5dfa50299 100644 --- a/src/USER-SMD/compute_smd_tlsph_defgrad.h +++ b/src/USER-SMD/compute_smd_tlsph_defgrad.h @@ -1,55 +1,55 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/tlsph/defgrad,ComputeSMDTLSPHDefgrad) #else #ifndef LMP_COMPUTE_SMD_TLSPH_DEFGRAD_H #define LMP_COMPUTE_SMD_TLSPH_DEFGRAD_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDTLSPHDefgrad : public Compute { public: ComputeSMDTLSPHDefgrad(class LAMMPS *, int, char **); ~ComputeSMDTLSPHDefgrad(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double **defgradVector; }; } #endif #endif diff --git a/src/USER-SMD/compute_smd_tlsph_dt.h b/src/USER-SMD/compute_smd_tlsph_dt.h index 16969a05b..09bf6c972 100644 --- a/src/USER-SMD/compute_smd_tlsph_dt.h +++ b/src/USER-SMD/compute_smd_tlsph_dt.h @@ -1,55 +1,55 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/tlsph/dt,ComputeSMDTlsphDt) #else #ifndef LMP_COMPUTE_SMD_TLSPH_DT_H #define LMP_COMPUTE_SMD_TLSPH_DT_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDTlsphDt : public Compute { public: ComputeSMDTlsphDt(class LAMMPS *, int, char **); ~ComputeSMDTlsphDt(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double *dt_vector; }; } #endif #endif diff --git a/src/USER-SMD/compute_smd_tlsph_num_neighs.h b/src/USER-SMD/compute_smd_tlsph_num_neighs.h index 77e4c5838..da649fbce 100644 --- a/src/USER-SMD/compute_smd_tlsph_num_neighs.h +++ b/src/USER-SMD/compute_smd_tlsph_num_neighs.h @@ -1,69 +1,69 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/tlsph/num/neighs,ComputeSMDTLSPHNumNeighs) #else #ifndef LMP_COMPUTE_SMD_TLSPH_NUM_NEIGHS_H #define LMP_COMPUTE_SMD_TLSPH_NUM_NEIGHS_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDTLSPHNumNeighs : public Compute { public: ComputeSMDTLSPHNumNeighs(class LAMMPS *, int, char **); ~ComputeSMDTLSPHNumNeighs(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double *numNeighsRefConfigOutput; }; } #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. W: More than one compute ke/atom It is not efficient to use compute ke/atom more than once. */ diff --git a/src/USER-SMD/compute_smd_tlsph_shape.h b/src/USER-SMD/compute_smd_tlsph_shape.h index 167e2b67e..193657870 100644 --- a/src/USER-SMD/compute_smd_tlsph_shape.h +++ b/src/USER-SMD/compute_smd_tlsph_shape.h @@ -1,55 +1,55 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/tlsph/shape,ComputeSmdTlsphShape) #else #ifndef LMP_COMPUTE_SMD_TLSPH_SHAPE_H #define LMP_COMPUTE_SMD_TLSPH_SHAPE_H #include "compute.h" namespace LAMMPS_NS { class ComputeSmdTlsphShape : public Compute { public: ComputeSmdTlsphShape(class LAMMPS *, int, char **); ~ComputeSmdTlsphShape(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double **strainVector; }; } #endif #endif diff --git a/src/USER-SMD/compute_smd_tlsph_strain.h b/src/USER-SMD/compute_smd_tlsph_strain.h index 199190c8b..1294af2f4 100644 --- a/src/USER-SMD/compute_smd_tlsph_strain.h +++ b/src/USER-SMD/compute_smd_tlsph_strain.h @@ -1,55 +1,55 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/tlsph/strain,ComputeSMDTLSPHstrain) #else #ifndef LMP_COMPUTE_SMD_TLSPH_STRAIN_H #define LMP_COMPUTE_SMD_TLSPH_STRAIN_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDTLSPHstrain : public Compute { public: ComputeSMDTLSPHstrain(class LAMMPS *, int, char **); ~ComputeSMDTLSPHstrain(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double **strainVector; }; } #endif #endif diff --git a/src/USER-SMD/compute_smd_tlsph_strain_rate.h b/src/USER-SMD/compute_smd_tlsph_strain_rate.h index 9924f5e1c..cc4ed9f5e 100644 --- a/src/USER-SMD/compute_smd_tlsph_strain_rate.h +++ b/src/USER-SMD/compute_smd_tlsph_strain_rate.h @@ -1,55 +1,55 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/tlsph/strain/rate,ComputeSMDTLSPHStrainRate) #else #ifndef LMP_COMPUTE_SMD_TLSPH_STRAIN_RATE_H #define LMP_COMPUTE_SMD_TLSPH_STRAIN_RATE_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDTLSPHStrainRate : public Compute { public: ComputeSMDTLSPHStrainRate(class LAMMPS *, int, char **); ~ComputeSMDTLSPHStrainRate(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double **strain_rate_array; }; } #endif #endif diff --git a/src/USER-SMD/compute_smd_tlsph_stress.h b/src/USER-SMD/compute_smd_tlsph_stress.h index 3a8f6610b..bf9079bb4 100644 --- a/src/USER-SMD/compute_smd_tlsph_stress.h +++ b/src/USER-SMD/compute_smd_tlsph_stress.h @@ -1,55 +1,55 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/tlsph/stress, ComputeSMDTLSPHStress) #else #ifndef LMP_COMPUTE_SMD_TLSPH_STRESS_H #define LMP_COMPUTE_SMD_TLSPH_STRESS_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDTLSPHStress : public Compute { public: ComputeSMDTLSPHStress(class LAMMPS *, int, char **); ~ComputeSMDTLSPHStress(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double **stress_array; }; } #endif #endif diff --git a/src/USER-SMD/compute_smd_triangle_mesh_vertices.h b/src/USER-SMD/compute_smd_triangle_mesh_vertices.h index 1a4ff295b..54c6055b9 100644 --- a/src/USER-SMD/compute_smd_triangle_mesh_vertices.h +++ b/src/USER-SMD/compute_smd_triangle_mesh_vertices.h @@ -1,55 +1,55 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/triangle/vertices,ComputeSMDTriangleVertices) #else #ifndef LMP_COMPUTE_SMD_TRIANGLE_VERTICES_H #define LMP_COMPUTE_SMD_TRIANGLE_VERTICES_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDTriangleVertices : public Compute { public: ComputeSMDTriangleVertices(class LAMMPS *, int, char **); ~ComputeSMDTriangleVertices(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double **outputVector; }; } #endif #endif diff --git a/src/USER-SMD/compute_smd_ulsph_effm.h b/src/USER-SMD/compute_smd_ulsph_effm.h index 3c2abd851..68981fe76 100644 --- a/src/USER-SMD/compute_smd_ulsph_effm.h +++ b/src/USER-SMD/compute_smd_ulsph_effm.h @@ -1,55 +1,55 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/ulsph/effm,ComputeSMD_Ulsph_Effm) #else #ifndef LMP_COMPUTE_SMD_ULSPH_EFFM_H #define LMP_COMPUTE_SMD_ULSPH_EFFM_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMD_Ulsph_Effm : public Compute { public: ComputeSMD_Ulsph_Effm(class LAMMPS *, int, char **); ~ComputeSMD_Ulsph_Effm(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double *dt_vector; }; } #endif #endif diff --git a/src/USER-SMD/compute_smd_ulsph_num_neighs.h b/src/USER-SMD/compute_smd_ulsph_num_neighs.h index 5af3bd930..57340f01b 100644 --- a/src/USER-SMD/compute_smd_ulsph_num_neighs.h +++ b/src/USER-SMD/compute_smd_ulsph_num_neighs.h @@ -1,69 +1,69 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/ulsph/num/neighs,ComputeSMDULSPHNumNeighs) #else #ifndef LMP_COMPUTE_SMD_ULSPH_NUM_NEIGHS_H #define LMP_COMPUTE_SMD_ULSPH_NUM_NEIGHS_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDULSPHNumNeighs : public Compute { public: ComputeSMDULSPHNumNeighs(class LAMMPS *, int, char **); ~ComputeSMDULSPHNumNeighs(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double *numNeighsOutput; }; } #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. W: More than one compute ke/atom It is not efficient to use compute ke/atom more than once. */ diff --git a/src/USER-SMD/compute_smd_ulsph_strain.h b/src/USER-SMD/compute_smd_ulsph_strain.h index 2e266f4e2..a5796f34e 100644 --- a/src/USER-SMD/compute_smd_ulsph_strain.h +++ b/src/USER-SMD/compute_smd_ulsph_strain.h @@ -1,55 +1,55 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/ulsph/strain,ComputeSMDULSPHstrain) #else #ifndef LMP_COMPUTE_SMD_ULSPH_STRAIN_H #define LMP_COMPUTE_SMD_ULSPH_STRAIN_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDULSPHstrain : public Compute { public: ComputeSMDULSPHstrain(class LAMMPS *, int, char **); ~ComputeSMDULSPHstrain(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double **strainVector; }; } #endif #endif diff --git a/src/USER-SMD/compute_smd_ulsph_strain_rate.h b/src/USER-SMD/compute_smd_ulsph_strain_rate.h index d2d43ef97..fc6df758e 100644 --- a/src/USER-SMD/compute_smd_ulsph_strain_rate.h +++ b/src/USER-SMD/compute_smd_ulsph_strain_rate.h @@ -1,55 +1,55 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/ulsph/strain/rate,ComputeSMDULSPHStrainRate) #else #ifndef LMP_COMPUTE_SMD_ULSPH_STRAIN_RATE_H #define LMP_COMPUTE_SMD_ULSPH_STRAIN_RATE_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDULSPHStrainRate : public Compute { public: ComputeSMDULSPHStrainRate(class LAMMPS *, int, char **); ~ComputeSMDULSPHStrainRate(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double **strain_rate_array; }; } #endif #endif diff --git a/src/USER-SMD/compute_smd_ulsph_stress.h b/src/USER-SMD/compute_smd_ulsph_stress.h index c96244970..4e27a5172 100644 --- a/src/USER-SMD/compute_smd_ulsph_stress.h +++ b/src/USER-SMD/compute_smd_ulsph_stress.h @@ -1,55 +1,55 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/ulsph/stress, ComputeSMDULSPHStress) #else #ifndef LMP_COMPUTE_SMD_ULSPH_STRESS_H #define LMP_COMPUTE_SMD_ULSPH_STRESS_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDULSPHStress : public Compute { public: ComputeSMDULSPHStress(class LAMMPS *, int, char **); ~ComputeSMDULSPHStress(); void init(); void compute_peratom(); double memory_usage(); private: int nmax; double **stress_array; }; } #endif #endif diff --git a/src/USER-SMD/compute_smd_vol.h b/src/USER-SMD/compute_smd_vol.h index e946ed85c..5525ce57c 100644 --- a/src/USER-SMD/compute_smd_vol.h +++ b/src/USER-SMD/compute_smd_vol.h @@ -1,56 +1,56 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 COMPUTE_CLASS ComputeStyle(smd/volume,ComputeSMDVol) #else #ifndef LMP_COMPUTE_SMD_VOL_H #define LMP_COMPUTE_SMD_VOL_H #include "compute.h" namespace LAMMPS_NS { class ComputeSMDVol : public Compute { public: ComputeSMDVol(class LAMMPS *, int, char **); ~ComputeSMDVol(); void init(); void compute_peratom(); double compute_scalar(); double memory_usage(); private: int nmax; double *volVector; }; } #endif #endif diff --git a/src/USER-SMD/fix_smd_adjust_dt.h b/src/USER-SMD/fix_smd_adjust_dt.h index 3b96d76d7..d7d8c922f 100644 --- a/src/USER-SMD/fix_smd_adjust_dt.h +++ b/src/USER-SMD/fix_smd_adjust_dt.h @@ -1,80 +1,80 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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(smd/adjust_dt,FixSMDTlsphDtReset) #else #ifndef LMP_FIX_TLSPH_DT_RESET_H #define LMP_FIX_TLSPH_DT_RESET_H #include "fix.h" namespace LAMMPS_NS { class FixSMDTlsphDtReset: public Fix { public: FixSMDTlsphDtReset(class LAMMPS *, int, char **); ~FixSMDTlsphDtReset() { } int setmask(); void init(); void setup(int); void initial_integrate(int); void end_of_step(); double compute_scalar(); void write_restart(FILE *); void restart(char *); private: double safety_factor; double dt, t_elapsed; }; } #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: Use of fix dt/reset with undefined lattice Must use lattice command with fix dt/reset command if units option is set to lattice. W: Dump dcd/xtc timestamp may be wrong with fix dt/reset If the fix changes the timestep, the dump dcd file will not reflect the change. */ diff --git a/src/USER-SMD/fix_smd_integrate_tlsph.h b/src/USER-SMD/fix_smd_integrate_tlsph.h index 7119f8d91..ca047f2df 100644 --- a/src/USER-SMD/fix_smd_integrate_tlsph.h +++ b/src/USER-SMD/fix_smd_integrate_tlsph.h @@ -1,73 +1,73 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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(smd/integrate_tlsph,FixSMDIntegrateTlsph) #else #ifndef LMP_FIX_SMD_INTEGRATE_TLSPH_H #define LMP_FIX_SMD_INTEGRATE_TLSPH_H #include "fix.h" namespace LAMMPS_NS { class FixSMDIntegrateTlsph: public Fix { friend class Neighbor; friend class PairTlsph; public: FixSMDIntegrateTlsph(class LAMMPS *, int, char **); virtual ~FixSMDIntegrateTlsph() { } int setmask(); virtual void init(); virtual void initial_integrate(int); virtual void final_integrate(); virtual void reset_dt(); protected: double dtv, dtf, vlimit, vlimitsq; int mass_require; bool xsphFlag; class Pair *pair; }; } #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. */ diff --git a/src/USER-SMD/fix_smd_integrate_ulsph.h b/src/USER-SMD/fix_smd_integrate_ulsph.h index 19ae31a59..ea4f46ce5 100644 --- a/src/USER-SMD/fix_smd_integrate_ulsph.h +++ b/src/USER-SMD/fix_smd_integrate_ulsph.h @@ -1,64 +1,64 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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(smd/integrate_ulsph,FixSMDIntegrateUlsph) #else #ifndef LMP_FIX_SMD_INTEGRATE_ULSPH_H #define LMP_FIX_SMD_INTEGRATE_ULSPH_H #include "fix.h" namespace LAMMPS_NS { class FixSMDIntegrateUlsph : public Fix { public: FixSMDIntegrateUlsph(class LAMMPS *, int, char **); int setmask(); virtual void init(); virtual void initial_integrate(int); virtual void final_integrate(); void reset_dt(); private: class NeighList *list; protected: double dtv,dtf, vlimit, vlimitsq;; int mass_require; bool xsphFlag; bool adjust_radius_flag; double adjust_radius_factor; int min_nn, max_nn; // number of SPH neighbors should lie within this interval class Pair *pair; }; } #endif #endif diff --git a/src/USER-SMD/fix_smd_move_triangulated_surface.h b/src/USER-SMD/fix_smd_move_triangulated_surface.h index ce4eaed88..c851d490c 100644 --- a/src/USER-SMD/fix_smd_move_triangulated_surface.h +++ b/src/USER-SMD/fix_smd_move_triangulated_surface.h @@ -1,63 +1,63 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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(smd/move_tri_surf,FixSMDMoveTriSurf) #else #ifndef LMP_FIX_SMD_INTEGRATE_TRIANGULAR_SURFACE_H #define LMP_FIX_SMD_INTEGRATE_TRIANGULAR_SURFACE_H #include #include "fix.h" namespace LAMMPS_NS { class FixSMDMoveTriSurf: public Fix { public: FixSMDMoveTriSurf(class LAMMPS *, int, char **); ~FixSMDMoveTriSurf(); int setmask(); virtual void init(); virtual void initial_integrate(int); void reset_dt(); int pack_forward_comm(int, int *, double *, int, int *); void unpack_forward_comm(int, int, double *); protected: double dtv; bool linearFlag, wiggleFlag, rotateFlag; double vx, vy, vz; Eigen::Vector3d rotation_axis, origin; double rotation_period; Eigen::Matrix3d u_cross, uxu; double wiggle_travel, wiggle_max_travel, wiggle_direction; }; } #endif #endif diff --git a/src/USER-SMD/fix_smd_setvel.h b/src/USER-SMD/fix_smd_setvel.h index 9e5fe642e..b987a56f6 100644 --- a/src/USER-SMD/fix_smd_setvel.h +++ b/src/USER-SMD/fix_smd_setvel.h @@ -1,95 +1,95 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* -*- 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(smd/setvelocity,FixSMDSetVel) #else #ifndef LMP_FIX_SMD_SET_VELOCITY_H #define LMP_FIX_SMD_SET_VELOCITY_H #include "fix.h" namespace LAMMPS_NS { class FixSMDSetVel : public Fix { public: FixSMDSetVel(class LAMMPS *, int, char **); ~FixSMDSetVel(); int setmask(); void init(); void setup(int); void min_setup(int); //void initial_integrate(int); void post_force(int); double compute_vector(int); double memory_usage(); private: double xvalue,yvalue,zvalue; int varflag,iregion; char *xstr,*ystr,*zstr; char *idregion; int xvar,yvar,zvar,xstyle,ystyle,zstyle; double foriginal[3],foriginal_all[3]; int force_flag; int nlevels_respa; int maxatom; double **sforce; }; } #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 ID for fix setforce does not exist Self-explanatory. E: Variable name for fix setforce does not exist Self-explanatory. E: Variable for fix setforce is invalid style Only equal-style variables can be used. E: Cannot use non-zero forces in an energy minimization Fix setforce cannot be used in this manner. Use fix addforce instead. */ diff --git a/src/USER-SMD/fix_smd_tlsph_reference_configuration.h b/src/USER-SMD/fix_smd_tlsph_reference_configuration.h index ede06151e..3ff693e9b 100644 --- a/src/USER-SMD/fix_smd_tlsph_reference_configuration.h +++ b/src/USER-SMD/fix_smd_tlsph_reference_configuration.h @@ -1,86 +1,86 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * This file is based on the FixShearHistory class. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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(SMD_TLSPH_NEIGHBORS,FixSMD_TLSPH_ReferenceConfiguration) #else #ifndef LMP_FIX_SMD_TLSPH_REFERENCE_H #define LMP_FIX_SMD_TLSPH_REFERENCE_H #include "fix.h" #include "my_page.h" namespace LAMMPS_NS { class FixSMD_TLSPH_ReferenceConfiguration: public Fix { friend class Neighbor; friend class PairTlsph; public: FixSMD_TLSPH_ReferenceConfiguration(class LAMMPS *, int, char **); ~FixSMD_TLSPH_ReferenceConfiguration(); int setmask(); void init(); void setup(int); void pre_exchange(); int pack_forward_comm(int, int *, double *, int, int *); void unpack_forward_comm(int, int, double *); double memory_usage(); void grow_arrays(int); void copy_arrays(int, int, 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(); bool crack_exclude(int i, int j); bool get_line_intersection(int i, int j); protected: int updateFlag; // flag to update reference configuration int nmax; int maxpartner; int *npartner; // # of touching partners of each atom tagint **partner; // global atom IDs for the partners float **wfd_list, **wf_list, **energy_per_bond; float **degradation_ij; // per-pair interaction degradation status class Pair *pair; }; } #endif #endif diff --git a/src/USER-SMD/fix_smd_wall_surface.h b/src/USER-SMD/fix_smd_wall_surface.h index 8bd7002a9..a32319f48 100644 --- a/src/USER-SMD/fix_smd_wall_surface.h +++ b/src/USER-SMD/fix_smd_wall_surface.h @@ -1,51 +1,51 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(smd/wall_surface,FixSMDWallSurface) #else #ifndef LMP_FIX_SMD_WALL_SURFACE_H #define LMP_FIX_SMD_WALL_SURFACE_H #include "fix.h" namespace LAMMPS_NS { class FixSMDWallSurface: public Fix { public: FixSMDWallSurface(class LAMMPS *, int, char **); virtual ~FixSMDWallSurface(); int setmask(); void init(); void setup(int); void min_setup(int); int count_words(const char *line); void read_triangles(int pass); private: int first; // flag for first time initialization double sublo[3], subhi[3]; // epsilon-extended proc sub-box for adding atoms; char *filename; int wall_particle_type; int wall_molecule_id; }; } #endif #endif diff --git a/src/USER-SMD/pair_smd_hertz.h b/src/USER-SMD/pair_smd_hertz.h index 6b40b6bb5..0866ef748 100644 --- a/src/USER-SMD/pair_smd_hertz.h +++ b/src/USER-SMD/pair_smd_hertz.h @@ -1,69 +1,69 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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(smd/hertz,PairHertz) #else #ifndef LMP_SMD_HERTZ_H #define LMP_SMD_HERTZ_H #include "pair.h" namespace LAMMPS_NS { class PairHertz : public Pair { public: PairHertz(class LAMMPS *); virtual ~PairHertz(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); void init_style(); void init_list(int, class NeighList *); virtual double memory_usage(); void *extract(const char *, int &); protected: double **bulkmodulus; double **kn; double *onerad_dynamic,*onerad_frozen; double *maxrad_dynamic,*maxrad_frozen; double scale; double stable_time_increment; // stable time step size void allocate(); }; } #endif #endif diff --git a/src/USER-SMD/pair_smd_tlsph.h b/src/USER-SMD/pair_smd_tlsph.h index 17db11b81..4c9db9209 100644 --- a/src/USER-SMD/pair_smd_tlsph.h +++ b/src/USER-SMD/pair_smd_tlsph.h @@ -1,224 +1,224 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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(smd/tlsph,PairTlsph) #else #ifndef LMP_TLSPH_NEW_H #define LMP_TLSPH_NEW_H #include "pair.h" #include namespace LAMMPS_NS { class PairTlsph: public Pair { public: PairTlsph(class LAMMPS *); virtual ~PairTlsph(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); void init_style(); void init_list(int, class NeighList *); void write_restart_settings(FILE *) { } void read_restart_settings(FILE *) { } virtual double memory_usage(); void compute_shape_matrix(void); void material_model(void); void *extract(const char *, int &); int pack_forward_comm(int, int *, double *, int, int *); void unpack_forward_comm(int, int, double *); void AssembleStress(); void PreCompute(); void ComputeForces(int eflag, int vflag); void effective_longitudinal_modulus(const int itype, const double dt, const double d_iso, const double p_rate, const Eigen::Matrix3d d_dev, const Eigen::Matrix3d sigma_dev_rate, const double damage, double &K_eff, double &mu_eff, double &M_eff); void ComputePressure(const int i, const double rho, const double mass_specific_energy, const double vol_specific_energy, const double pInitial, const double d_iso, double &pFinal, double &p_rate); void ComputeStressDeviator(const int i, const Eigen::Matrix3d sigmaInitial_dev, const Eigen::Matrix3d d_dev, Eigen::Matrix3d &sigmaFinal_dev, Eigen::Matrix3d &sigma_dev_rate, double &plastic_strain_increment); void ComputeDamage(const int i, const Eigen::Matrix3d strain, const Eigen::Matrix3d sigmaFinal, Eigen::Matrix3d &sigma_damaged); protected: void allocate(); char *suffix; /* * per-type arrays */ int *strengthModel, *eos; double *onerad_dynamic, *onerad_frozen, *maxrad_dynamic, *maxrad_frozen; /* * per atom arrays */ Eigen::Matrix3d *K, *PK1, *Fdot, *Fincr; Eigen::Matrix3d *R; // rotation matrix Eigen::Matrix3d *FincrInv; Eigen::Matrix3d *D, *W; // strain rate and spin tensor Eigen::Vector3d *smoothVelDifference; Eigen::Matrix3d *CauchyStress; double *detF, *particle_dt; double *hourglass_error; int *numNeighsRefConfig; int nmax; // max number of atoms on this proc double hMin; // minimum kernel radius for two particles double dtCFL; double dtRelative; // relative velocity of two particles, divided by sound speed int updateFlag; double update_threshold; // updateFlage is set to one if the relative displacement of a pair exceeds update_threshold double cut_comm; enum { UPDATE_NONE = 5000, UPDATE_CONSTANT_THRESHOLD = 5001, UPDATE_PAIRWISE_RATIO = 5002, }; enum { LINEAR_DEFGRAD = 0, STRENGTH_LINEAR = 1, STRENGTH_LINEAR_PLASTIC = 2, STRENGTH_JOHNSON_COOK = 3, STRENGTH_NONE = 4, EOS_LINEAR = 5, EOS_SHOCK = 6, EOS_POLYNOMIAL = 7, EOS_NONE = 8, REFERENCE_DENSITY = 9, YOUNGS_MODULUS = 10, POISSON_RATIO = 11, HOURGLASS_CONTROL_AMPLITUDE = 12, HEAT_CAPACITY = 13, LAME_LAMBDA = 14, SHEAR_MODULUS = 15, M_MODULUS = 16, SIGNAL_VELOCITY = 17, BULK_MODULUS = 18, VISCOSITY_Q1 = 19, VISCOSITY_Q2 = 20, YIELD_STRESS = 21, FAILURE_MAX_PLASTIC_STRAIN_THRESHOLD = 22, JC_A = 23, JC_B = 24, JC_a = 25, JC_C = 26, JC_epdot0 = 27, JC_T0 = 28, JC_Tmelt = 29, JC_M = 30, EOS_SHOCK_C0 = 31, EOS_SHOCK_S = 32, EOS_SHOCK_GAMMA = 33, HARDENING_PARAMETER = 34, FAILURE_MAX_PRINCIPAL_STRAIN_THRESHOLD = 35, FAILURE_MAX_PRINCIPAL_STRESS_THRESHOLD = 36, FAILURE_MAX_PAIRWISE_STRAIN_THRESHOLD = 37, EOS_POLYNOMIAL_C0 = 38, EOS_POLYNOMIAL_C1 = 39, EOS_POLYNOMIAL_C2 = 40, EOS_POLYNOMIAL_C3 = 41, EOS_POLYNOMIAL_C4 = 42, EOS_POLYNOMIAL_C5 = 43, EOS_POLYNOMIAL_C6 = 44, FAILURE_JC_D1 = 45, FAILURE_JC_D2 = 46, FAILURE_JC_D3 = 47, FAILURE_JC_D4 = 48, FAILURE_JC_EPDOT0 = 49, CRITICAL_ENERGY_RELEASE_RATE = 50, MAX_KEY_VALUE = 51 }; struct failure_types { // this is defined per type and determines which failure/damage model is active bool failure_none; bool failure_max_principal_strain; bool failure_max_principal_stress; bool failure_max_plastic_strain; bool failure_johnson_cook; bool failure_max_pairwise_strain; bool integration_point_wise; // true if failure model applies to stress/strain state of integration point bool failure_energy_release_rate; failure_types() { failure_none = true; failure_max_principal_strain = false; failure_max_principal_stress = false; failure_max_plastic_strain = false; failure_johnson_cook = false; failure_max_pairwise_strain = false; integration_point_wise = false; failure_energy_release_rate = false; //printf("constructed failure type\n"); } }; failure_types *failureModel; int ifix_tlsph; int update_method; class FixSMD_TLSPH_ReferenceConfiguration *fix_tlsph_reference_configuration; private: double **Lookup; // holds per-type material parameters for the quantities defined in enum statement above. bool first; // if first is true, do not perform any computations, beacuse reference configuration is not ready yet. }; } #endif #endif /* * materialCoeffs array for EOS parameters: * 1: rho0 * * * materialCoeffs array for strength parameters: * * Common * 10: maximum strain threshold for damage model * 11: maximum stress threshold for damage model * * Linear Plasticity model: * 12: plastic yield stress * * * Blei: rho = 11.34e-6, c0=2000, s=1.46, Gamma=2.77 * Stahl 1403: rho = 7.86e-3, c=4569, s=1.49, Gamma=2.17 */ diff --git a/src/USER-SMD/pair_smd_triangulated_surface.h b/src/USER-SMD/pair_smd_triangulated_surface.h index 633231364..c1eba7804 100644 --- a/src/USER-SMD/pair_smd_triangulated_surface.h +++ b/src/USER-SMD/pair_smd_triangulated_surface.h @@ -1,74 +1,74 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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(smd/tri_surface,PairTriSurf) #else #ifndef LMP_SMD_TRI_SURFACE_H #define LMP_SMD_TRI_SURFACE_H #include "pair.h" #include namespace LAMMPS_NS { class PairTriSurf : public Pair { public: PairTriSurf(class LAMMPS *); virtual ~PairTriSurf(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); void init_style(); void init_list(int, class NeighList *); virtual double memory_usage(); void PointTriangleDistance(const Eigen::Vector3d P, const Eigen::Vector3d TRI1, const Eigen::Vector3d TRI2, const Eigen::Vector3d TRI3, Eigen::Vector3d &CP, double &dist); double clamp(const double a, const double min, const double max); void *extract(const char *, int &); protected: double **bulkmodulus; double **kn; double *onerad_dynamic,*onerad_frozen; double *maxrad_dynamic,*maxrad_frozen; double scale; double stable_time_increment; // stable time step size void allocate(); }; } #endif #endif diff --git a/src/USER-SMD/pair_smd_ulsph.h b/src/USER-SMD/pair_smd_ulsph.h index 40ccc37e9..032079072 100644 --- a/src/USER-SMD/pair_smd_ulsph.h +++ b/src/USER-SMD/pair_smd_ulsph.h @@ -1,136 +1,136 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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(smd/ulsph,PairULSPH) #else #ifndef LMP_ULSPH_H #define LMP_ULSPH_H #include "pair.h" #include namespace LAMMPS_NS { class PairULSPH: public Pair { public: PairULSPH(class LAMMPS *); virtual ~PairULSPH(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); double init_one(int, int); void init_style(); void init_list(int, class NeighList *); virtual double memory_usage(); int pack_forward_comm(int, int *, double *, int, int *); void unpack_forward_comm(int, int, double *); void AssembleStressTensor(); void *extract(const char *, int &); void PreCompute(); void PreCompute_DensitySummation(); double effective_shear_modulus(const Eigen::Matrix3d d_dev, const Eigen::Matrix3d deltaStressDev, const double dt, const int itype); Eigen::Vector3d ComputeHourglassForce(const int i, const int itype, const int j, const int jtype, const Eigen::Vector3d dv, const Eigen::Vector3d xij, const Eigen::Vector3d g, const double c_ij, const double mu_ij, const double rho_ij); protected: double *c0_type; // reference speed of sound defined per particle type double *rho0; // reference mass density per type double *Q1; // linear artificial viscosity coeff int *eos, *viscosity, *strength; // eos and strength material models double **artificial_pressure; // true/false: use Monaghan's artificial pressure correction? double **artificial_stress; // artificial stress amplitude double *onerad_dynamic, *onerad_frozen; double *maxrad_dynamic, *maxrad_frozen; void allocate(); int nmax; // max number of atoms on this proc int *numNeighs; Eigen::Matrix3d *K; double *shepardWeight, *c0, *rho; Eigen::Vector3d *smoothVel; Eigen::Matrix3d *stressTensor, *L, *F; double dtCFL; private: // enumerate EOSs. MUST BE IN THE RANGE [1000, 2000) enum { EOS_LINEAR = 1000, EOS_PERFECT_GAS = 1001, EOS_TAIT = 1002, }; // enumerate physical viscosity models. MUST BE IN THE RANGE [2000, 3000) enum { VISCOSITY_NEWTON = 2000 }; // enumerate strength models. MUST BE IN THE RANGE [3000, 4000) enum { STRENGTH_LINEAR = 3000, STRENGTH_LINEAR_PLASTIC = 3001 }; // enumerate some quantitities and associate these with integer values such that they can be used for lookup in an array structure enum { NONE = 0, BULK_MODULUS = 1, HOURGLASS_CONTROL_AMPLITUDE = 2, EOS_TAIT_EXPONENT = 3, REFERENCE_SOUNDSPEED = 4, REFERENCE_DENSITY = 5, EOS_PERFECT_GAS_GAMMA = 6, SHEAR_MODULUS = 7, YIELD_STRENGTH = 8, YOUNGS_MODULUS = 9, POISSON_RATIO = 10, LAME_LAMBDA = 11, HEAT_CAPACITY = 12, M_MODULUS = 13, HARDENING_PARAMETER = 14, VISCOSITY_MU = 15, MAX_KEY_VALUE = 16 }; double **Lookup; // holds per-type material parameters for the quantities defined in enum statement above. bool velocity_gradient_required; int updateFlag; // indicates if any relative particle pair movement is significant compared to smoothing length bool density_summation, density_continuity, velocity_gradient, gradient_correction_flag; double *effm; }; } #endif #endif diff --git a/src/USER-SMD/smd_kernels.h b/src/USER-SMD/smd_kernels.h index ba40699fc..6621881f4 100644 --- a/src/USER-SMD/smd_kernels.h +++ b/src/USER-SMD/smd_kernels.h @@ -1,146 +1,146 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ #ifndef SMD_KERNEL_FUNCTIONS_H_ #define SMD_KERNEL_FUNCTIONS_H_ namespace SMD_Kernels { static inline double Kernel_Wendland_Quintic_NotNormalized(const double r, const double h) { if (r < h) { double q = 2.0 * r / h; return pow(1.0 - 0.5 * q, 4) * (2.0 * q + 1.0); } else { return 0.0; } } static inline double Kernel_Cubic_Spline(const double r, const double h) { double q = 2.0 * r / h; if (q > 2.0) { return 0.0; } else if ((q <= 2.0) && (q > 1.0)) { return pow(2.0 - q, 3.0) / 6.0; } else if ((q >= 0.0) && (q <= 1.0)) { return 2. / 3. - q * q + 0.5 * q * q * q; } else { return 0.0; } } static inline double Kernel_Barbara(const double r, const double h) { double arg = (1.570796327 * (r + h)) / h; double hsq = h * h; //wf = (1.680351548 * (cos(arg) + 1.)) / hsq; return -2.639490040 * sin(arg) / (hsq * h); } static inline void spiky_kernel_and_derivative(const double h, const double r, const int dimension, double &wf, double &wfd) { /* * Spiky kernel */ if (r > h) { printf("r=%f > h=%f in Spiky kernel\n", r, h); wf = wfd = 0.0; return; } double hr = h - r; // [m] if (dimension == 2) { double n = 0.3141592654e0 * h * h * h * h * h; // [m^5] wfd = -3.0e0 * hr * hr / n; // [m*m/m^5] = [1/m^3] ==> correct for dW/dr in 2D wf = -0.333333333333e0 * hr * wfd; // [m/m^3] ==> [1/m^2] correct for W in 2D } else { wfd = -14.0323944878e0 * hr * hr / (h * h * h * h * h * h); // [1/m^4] ==> correct for dW/dr in 3D wf = -0.333333333333e0 * hr * wfd; // [m/m^4] ==> [1/m^3] correct for W in 3D } // alternative formulation // double hr = h - r; // // /* // * Spiky kernel // */ // // if (domain->dimension == 2) { // double h5 = h * h * h * h * h; // wf = 3.183098861e0 * hr * hr * hr / h5; // wfd = -9.549296583 * hr * hr / h5; // // } else { // double h6 = h * h * h * h * h * h; // wf = 4.774648292 * hr * hr * hr / h6; // wfd = -14.32394487 * hr * hr / h6; // } // } } static inline void barbara_kernel_and_derivative(const double h, const double r, const int dimension, double &wf, double &wfd) { /* * Barbara kernel */ double arg = (1.570796327 * (r + h)) / h; double hsq = h * h; if (r > h) { printf("r = %f > h = %f in barbara kernel function\n", r, h); exit(1); //wf = wfd = 0.0; //return; } if (dimension == 2) { wf = (1.680351548 * (cos(arg) + 1.)) / hsq; wfd = -2.639490040 * sin(arg) / (hsq * h); } else { wf = 2.051578323 * (cos(arg) + 1.) / (hsq * h); wfd = -3.222611694 * sin(arg) / (hsq * hsq); } } /* * compute a normalized smoothing kernel only */ static inline void Poly6Kernel(const double hsq, const double h, const double rsq, const int dimension, double &wf) { double tmp = hsq - rsq; if (dimension == 2) { wf = tmp * tmp * tmp / (0.7853981635e0 * hsq * hsq * hsq * hsq); } else { wf = tmp * tmp * tmp / (0.6382918409e0 * hsq * hsq * hsq * hsq * h); } } /* * M4 Prime Kernel */ static inline void M4PrimeKernel(const double s, double &wf) { if (s < 1.0) { //wf = 1.0 - 2.5 * s * s + (3./2.) * s * s * s; wf = 1.0 - s * s *(2.5 -1.5 *s); } else if (s < 2.0) { //wf = 0.5 * (1.0 - s) * ((2.0 - s) * (2.0 - s)); wf = 2.0 + (-4.0 + (2.5 - 0.5 * s)*s)*s; } else { wf = 0.0; } } } #endif /* SMD_KERNEL_FUNCTIONS_H_ */ diff --git a/src/USER-SMD/smd_material_models.h b/src/USER-SMD/smd_material_models.h index 858c5bbbd..c6b6f8d94 100644 --- a/src/USER-SMD/smd_material_models.h +++ b/src/USER-SMD/smd_material_models.h @@ -1,65 +1,65 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- 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 SMD_MATERIAL_MODELS_H_ #define SMD_MATERIAL_MODELS_H_ using namespace Eigen; /* * EOS models */ void LinearEOS(double lambda, double pInitial, double d, double dt, double &pFinal, double &p_rate); void ShockEOS(double rho, double rho0, double e, double e0, double c0, double S, double Gamma, double pInitial, double dt, double &pFinal, double &p_rate); void polynomialEOS(double rho, double rho0, double e, double C0, double C1, double C2, double C3, double C4, double C5, double C6, double pInitial, double dt, double &pFinal, double &p_rate); void TaitEOS_density(const double exponent, const double c0_reference, const double rho_reference, const double rho_current, double &pressure, double &sound_speed); void PerfectGasEOS(const double gamma, const double vol, const double mass, const double energy, double &pFinal__, double &c0); /* * Material strength models */ void LinearStrength(const double mu, const Matrix3d sigmaInitial_dev, const Matrix3d d_dev, const double dt, Matrix3d &sigmaFinal_dev__, Matrix3d &sigma_dev_rate__); void LinearPlasticStrength(const double G, const double yieldStress, const Matrix3d sigmaInitial_dev, const Matrix3d d_dev, const double dt, Matrix3d &sigmaFinal_dev__, Matrix3d &sigma_dev_rate__, double &plastic_strain_increment); void JohnsonCookStrength(const double G, const double cp, const double espec, const double A, const double B, const double a, const double C, const double epdot0, const double T0, const double Tmelt, const double M, const double dt, const double ep, const double epdot, const Matrix3d sigmaInitial_dev, const Matrix3d d_dev, Matrix3d &sigmaFinal_dev__, Matrix3d &sigma_dev_rate__, double &plastic_strain_increment); /* * Damage models */ bool IsotropicMaxStrainDamage(const Matrix3d E, const double maxStrain); bool IsotropicMaxStressDamage(const Matrix3d E, const double maxStrain); double JohnsonCookFailureStrain(const double p, const Matrix3d Sdev, const double d1, const double d2, const double d3, const double d4, const double epdot0, const double epdot); #endif /* SMD_MATERIAL_MODELS_H_ */ diff --git a/src/USER-SMD/smd_math.h b/src/USER-SMD/smd_math.h index 5352cfccf..b7bf9c112 100644 --- a/src/USER-SMD/smd_math.h +++ b/src/USER-SMD/smd_math.h @@ -1,287 +1,287 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- * * *** Smooth Mach Dynamics *** * * This file is part of the USER-SMD package for LAMMPS. * Copyright (2014) Georg C. Ganzenmueller, georg.ganzenmueller@emi.fhg.de * Fraunhofer Ernst-Mach Institute for High-Speed Dynamics, EMI, * Eckerstrasse 4, D-79104 Freiburg i.Br, Germany. * * ----------------------------------------------------------------------- */ //test #ifndef SMD_MATH_H_ #define SMD_MATH_H_ #include #include using namespace Eigen; using namespace std; namespace SMD_Math { static inline void LimitDoubleMagnitude(double &x, const double limit) { /* * if |x| exceeds limit, set x to limit with the sign of x */ if (fabs(x) > limit) { // limit delVdotDelR to a fraction of speed of sound x = limit * copysign(1, x); } } /* * deviator of a tensor */ static inline Matrix3d Deviator(const Matrix3d M) { Matrix3d eye; eye.setIdentity(); eye *= M.trace() / 3.0; return M - eye; } /* * Polar Decomposition M = R * T * where R is a rotation and T a pure translation/stretch matrix. * * The decomposition is achieved using SVD, i.e. M = U S V^T, * where U = R V and S is diagonal. * * * For any physically admissible deformation gradient, the determinant of R must equal +1. * However, scenerios can arise, where the particles interpenetrate and cause inversion, leading to a determinant of R equal to -1. * In this case, the inversion direction is heuristically identified with the eigenvector of the smallest entry of S, which should work for most cases. * The sign of this corresponding eigenvalue is flipped, the original matrix M is recomputed using the flipped S, and the rotation and translation matrices are * obtained again from an SVD. The rotation should proper now, i.e., det(R) = +1. */ static inline bool PolDec(Matrix3d M, Matrix3d &R, Matrix3d &T, bool scaleF) { JacobiSVD svd(M, ComputeFullU | ComputeFullV); // SVD(A) = U S V* Vector3d S_eigenvalues = svd.singularValues(); Matrix3d S = svd.singularValues().asDiagonal(); Matrix3d U = svd.matrixU(); Matrix3d V = svd.matrixV(); Matrix3d eye; eye.setIdentity(); // now do polar decomposition into M = R * T, where R is rotation // and T is translation matrix R = U * V.transpose(); T = V * S * V.transpose(); if (R.determinant() < 0.0) { // this is an improper rotation // identify the smallest entry in S and flip its sign int imin; S_eigenvalues.minCoeff(&imin); S(imin, imin) *= -1.0; R = M * V * S.inverse() * V.transpose(); // recompute R using flipped stretch eigenvalues } /* * scale S to avoid small principal strains */ if (scaleF) { double min = 0.3; // 0.3^2 = 0.09, should suffice for most problems double max = 2.0; for (int i = 0; i < 3; i++) { if (S(i, i) < min) { S(i, i) = min; } else if (S(i, i) > max) { S(i, i) = max; } } T = V * S * V.transpose(); } if (R.determinant() > 0.0) { return true; } else { return false; } } /* * Pseudo-inverse via SVD */ static inline void pseudo_inverse_SVD(Matrix3d &M) { //JacobiSVD < Matrix3d > svd(M, ComputeFullU | ComputeFullV); JacobiSVD svd(M, ComputeFullU); // one Eigevector base is sufficient because matrix is square and symmetric Vector3d singularValuesInv; Vector3d singularValues = svd.singularValues(); //cout << "Here is the matrix V:" << endl << V * singularValues.asDiagonal() * U << endl; //cout << "Its singular values are:" << endl << singularValues << endl; double pinvtoler = 1.0e-16; // 2d machining example goes unstable if this value is increased (1.0e-16). for (int row = 0; row < 3; row++) { if (singularValues(row) > pinvtoler) { singularValuesInv(row) = 1.0 / singularValues(row); } else { singularValuesInv(row) = 0.0; } } M = svd.matrixU() * singularValuesInv.asDiagonal() * svd.matrixU().transpose(); // JacobiSVD < Matrix3d > svd(M, ComputeFullU | ComputeFullV); // // Vector3d singularValuesInv; // Vector3d singularValues = svd.singularValues(); // // //cout << "Here is the matrix V:" << endl << V * singularValues.asDiagonal() * U << endl; // //cout << "Its singular values are:" << endl << singularValues << endl; // // double pinvtoler = 1.0e-16; // 2d machining example goes unstable if this value is increased (1.0e-16). // for (int row = 0; row < 3; row++) { // if (singularValues(row) > pinvtoler) { // singularValuesInv(row) = 1.0 / singularValues(row); // } else { // singularValuesInv(row) = 0.0; // } // } // // M = svd.matrixU() * singularValuesInv.asDiagonal() * svd.matrixV().transpose(); } /* * test if two matrices are equal */ static inline double TestMatricesEqual(Matrix3d A, Matrix3d B, double eps) { Matrix3d diff; diff = A - B; double norm = diff.norm(); if (norm > eps) { printf("Matrices A and B are not equal! The L2-norm difference is: %g\n", norm); cout << "Here is matrix A:" << endl << A << endl; cout << "Here is matrix B:" << endl << B << endl; } return norm; } /* ---------------------------------------------------------------------- Limit eigenvalues of a matrix to upper and lower bounds. ------------------------------------------------------------------------- */ static inline Matrix3d LimitEigenvalues(Matrix3d S, double limitEigenvalue) { /* * compute Eigenvalues of matrix S */ SelfAdjointEigenSolver < Matrix3d > es; es.compute(S); double max_eigenvalue = es.eigenvalues().maxCoeff(); double min_eigenvalue = es.eigenvalues().minCoeff(); double amax_eigenvalue = fabs(max_eigenvalue); double amin_eigenvalue = fabs(min_eigenvalue); if ((amax_eigenvalue > limitEigenvalue) || (amin_eigenvalue > limitEigenvalue)) { if (amax_eigenvalue > amin_eigenvalue) { // need to scale with max_eigenvalue double scale = amax_eigenvalue / limitEigenvalue; Matrix3d V = es.eigenvectors(); Matrix3d S_diag = V.inverse() * S * V; // diagonalized input matrix S_diag /= scale; Matrix3d S_scaled = V * S_diag * V.inverse(); // undiagonalize matrix return S_scaled; } else { // need to scale using min_eigenvalue double scale = amin_eigenvalue / limitEigenvalue; Matrix3d V = es.eigenvectors(); Matrix3d S_diag = V.inverse() * S * V; // diagonalized input matrix S_diag /= scale; Matrix3d S_scaled = V * S_diag * V.inverse(); // undiagonalize matrix return S_scaled; } } else { // limiting does not apply return S; } } static inline bool LimitMinMaxEigenvalues(Matrix3d &S, double min, double max) { /* * compute Eigenvalues of matrix S */ SelfAdjointEigenSolver < Matrix3d > es; es.compute(S); if ((es.eigenvalues().maxCoeff() > max) || (es.eigenvalues().minCoeff() < min)) { Matrix3d S_diag = es.eigenvalues().asDiagonal(); Matrix3d V = es.eigenvectors(); for (int i = 0; i < 3; i++) { if (S_diag(i, i) < min) { //printf("limiting eigenvalue %f --> %f\n", S_diag(i, i), min); //printf("these are the eigenvalues of U: %f %f %f\n", es.eigenvalues()(0), es.eigenvalues()(1), es.eigenvalues()(2)); S_diag(i, i) = min; } else if (S_diag(i, i) > max) { //printf("limiting eigenvalue %f --> %f\n", S_diag(i, i), max); S_diag(i, i) = max; } } S = V * S_diag * V.inverse(); // undiagonalize matrix return true; } else { return false; } } static inline void reconstruct_rank_deficient_shape_matrix(Matrix3d &K) { JacobiSVD svd(K, ComputeFullU | ComputeFullV); Vector3d singularValues = svd.singularValues(); for (int i = 0; i < 3; i++) { if (singularValues(i) < 1.0e-8) { singularValues(i) = 1.0; } } // int imin; // double minev = singularValues.minCoeff(&imin); // // printf("min eigenvalue=%f has index %d\n", minev, imin); // Vector3d singularVec = U.col(0).cross(U.col(1)); // cout << "the eigenvalues are " << endl << singularValues << endl; // cout << "the singular vector is " << endl << singularVec << endl; // // // reconstruct original K // // singularValues(2) = 1.0; K = svd.matrixU() * singularValues.asDiagonal() * svd.matrixV().transpose(); //cout << "the reconstructed K is " << endl << K << endl; //exit(1); } /* ---------------------------------------------------------------------- helper functions for crack_exclude ------------------------------------------------------------------------- */ static inline bool IsOnSegment(double xi, double yi, double xj, double yj, double xk, double yk) { return (xi <= xk || xj <= xk) && (xk <= xi || xk <= xj) && (yi <= yk || yj <= yk) && (yk <= yi || yk <= yj); } static inline char ComputeDirection(double xi, double yi, double xj, double yj, double xk, double yk) { double a = (xk - xi) * (yj - yi); double b = (xj - xi) * (yk - yi); return a < b ? -1.0 : a > b ? 1.0 : 0; } /** Do line segments (x1, y1)--(x2, y2) and (x3, y3)--(x4, y4) intersect? */ static inline bool DoLineSegmentsIntersect(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) { char d1 = ComputeDirection(x3, y3, x4, y4, x1, y1); char d2 = ComputeDirection(x3, y3, x4, y4, x2, y2); char d3 = ComputeDirection(x1, y1, x2, y2, x3, y3); char d4 = ComputeDirection(x1, y1, x2, y2, x4, y4); return (((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) && ((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0))) || (d1 == 0 && IsOnSegment(x3, y3, x4, y4, x1, y1)) || (d2 == 0 && IsOnSegment(x3, y3, x4, y4, x2, y2)) || (d3 == 0 && IsOnSegment(x1, y1, x2, y2, x3, y3)) || (d4 == 0 && IsOnSegment(x1, y1, x2, y2, x4, y4)); } } #endif /* SMD_MATH_H_ */ diff --git a/src/USER-SMTBQ/pair_smtbq.h b/src/USER-SMTBQ/pair_smtbq.h index 49fbe8768..25dfe9888 100644 --- a/src/USER-SMTBQ/pair_smtbq.h +++ b/src/USER-SMTBQ/pair_smtbq.h @@ -1,195 +1,195 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(smtbq,PairSMTBQ) #else #ifndef LMP_PAIR_SMTBQ_H #define LMP_PAIR_SMTBQ_H #include "pair.h" namespace LAMMPS_NS { class PairSMTBQ : public Pair { public: PairSMTBQ(class LAMMPS *); virtual ~PairSMTBQ(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); double init_one(int, int); double memory_usage(); protected: struct Param { double sto,n0,ne,chi,dj; double R,dzeta; //Rayon slater double cutsq; double qform, masse; // Charge formelle char *nom; }; struct Intparam { double a,p,ksi,q,r0,dc1,dc2; double abuck,rhobuck,neig_cut,aOO,bOO,r1OO,r2OO; char *typepot,*mode; int intsm; }; double rmin,dr,ds; // table parameter int kmax; bigint Qstep; // Frequency of charge resolution double precision; // acuracy of convergence int loopmax; // max of interation double cutmax; // max cutoff for all elements int nelements; // # of unique elements char **elements; // names of unique elements char *QEqMode; // name of QEqMode char *Bavard; // Verbose parameter char *writepot; // write or not the electronegativity component char *writeenerg; // write or not the energy component char *QInitMode; // mode of initialization of charges double zlim1QEq; // z limit for QEq equilibration double zlim2QEq; // z limit for QEq equilibration double QOxInit; // Initial charge for oxygen atoms (if the charge is not specified) int *map; // mapping from atom types to elements int nparams; // # of stored parameter sets int maxparam; // max # of parameter sets int maxintparam; // max # of interaction sets int maxintsm; // max # of interaction SM double r1Coord,r2Coord; Param *params; // parameter set for an I atom Intparam *intparams; // parameter set for an I interaction int nmax,*nQEqall,*nQEqaall,*nQEqcall; double *qf,*q1,*q2,Nevery,Neverypot; // Coulombian interaction double *esm, **fafb, **dfafb, *fafbOxOxSurf, *dfafbOxOxSurf, *fafbTiOxSurf,*dfafbTiOxSurf; double *potqn, *dpotqn, Vself, *Zsm,*coord, *fafbOxOxBB, *dfafbOxOxBB,*fafbTiOxBB, *dfafbTiOxBB ; int **intype, **coultype; int *NCo; double coordOxBulk,coordOxSurf,ROxSurf,coordOxBB,ROxBB; // Covalent interaction double *ecov, *potmad, *potself, *potcov, *chimet; double **tabsmb,**dtabsmb, **tabsmr, **dtabsmr, *sbcov, *sbmet; double ncov; // Neighbor Table int nteam,cluster,*hybrid; int *nvsm, **vsm, *flag_QEq; // Parallelisation int me, nproc; double *tab_comm; // GAMMAS function double *fct; // HERE its routines // ===================================== void allocate(); virtual void read_file(char *); void tabsm(); void tabqeq(); void potqeq(int, int, double, double, double, double &, int, double &); void pot_ES (int, int, double, double &); void pot_ES2 (int, int, double, double &); double self(Param *, double); double qfo_self(Param *, double); virtual void repulsive(Intparam *, double, int, int, double &, int, double &); virtual void rep_OO (Intparam *, double, double &, int, double &); virtual void Attr_OO (Intparam *, double, double &, int, double &); virtual void attractive(Intparam *, double, int, int, double, int, double ); void f_att(Intparam *, int, int, double, double &) ; void pot_COV(Param *, int, double &); double potmet(Intparam *, double, int, double, int, double); double fcoupure(double, double, double); double fcoupured(double, double, double); double fcoup2(double, double, double); double Intfcoup2(double, double, double); double Primfcoup2(double, double, double); void groupBulkFromSlab_QEq(); void groupQEqAllParallel_QEq(); void groupQEqAll_QEq(); void groupSurface_QEq(); void QForce_charge(int); void Charge(); void Init_charge(int*, int*, int*); void CheckEnergyVSForce(); // =========================================== // Communication pack int pack_forward_comm (int, int*, double*, int, int*); void unpack_forward_comm (int, int, double*); int pack_reverse_comm (int, int, double*); void unpack_reverse_comm (int, int*, double*); void forward (double*); void reverse (double*); void forward_int (int*); void reverse_int (int*); int Tokenize( char* , char*** ); inline double vec3_dot(const double x[3], const double y[3]) const { return x[0]*y[0] + x[1]*y[1] + x[2]*y[2]; } template const T& min ( const T& a, const T& b ) { return !(b #include "compute_heat_flux_tally.h" #include "atom.h" #include "group.h" #include "pair.h" #include "update.h" #include "memory.h" #include "error.h" #include "force.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ ComputeHeatFluxTally::ComputeHeatFluxTally(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { if (narg < 4) error->all(FLERR,"Illegal compute heat/flux/tally command"); igroup2 = group->find(arg[3]); if (igroup2 == -1) error->all(FLERR,"Could not find compute heat/flux/tally second group ID"); groupbit2 = group->bitmask[igroup2]; vector_flag = 1; timeflag = 1; comm_reverse = 7; extvector = 1; size_vector = 6; peflag = 1; // we need Pair::ev_tally() to be run did_setup = 0; invoked_peratom = invoked_scalar = -1; nmax = -1; stress = NULL; eatom = NULL; vector = new double[size_vector]; heatj = new double[size_vector]; } /* ---------------------------------------------------------------------- */ ComputeHeatFluxTally::~ComputeHeatFluxTally() { if (force && force->pair) force->pair->del_tally_callback(this); memory->destroy(stress); memory->destroy(eatom); delete[] heatj; delete[] vector; } /* ---------------------------------------------------------------------- */ void ComputeHeatFluxTally::init() { if (force->pair == NULL) error->all(FLERR,"Trying to use compute heat/flux/tally without pair style"); else force->pair->add_tally_callback(this); if (comm->me == 0) { if (force->pair->single_enable == 0 || force->pair->manybody_flag) error->warning(FLERR,"Compute heat/flux/tally used with incompatible pair style"); if (force->bond || force->angle || force->dihedral || force->improper || force->kspace) error->warning(FLERR,"Compute heat/flux/tally only called from pair style"); } did_setup = -1; } /* ---------------------------------------------------------------------- */ void ComputeHeatFluxTally::pair_setup_callback(int, int) { const int ntotal = atom->nlocal + atom->nghost; // grow per-atom storage, if needed if (atom->nmax > nmax) { memory->destroy(stress); memory->destroy(eatom); nmax = atom->nmax; memory->create(stress,nmax,6,"heat/flux/tally:stress"); memory->create(eatom,nmax,"heat/flux/tally:eatom"); } // clear storage for (int i=0; i < ntotal; ++i) { eatom[i] = 0.0; stress[i][0] = 0.0; stress[i][1] = 0.0; stress[i][2] = 0.0; stress[i][3] = 0.0; stress[i][4] = 0.0; stress[i][5] = 0.0; } for (int i=0; i < size_vector; ++i) vector[i] = heatj[i] = 0.0; did_setup = update->ntimestep; } /* ---------------------------------------------------------------------- */ void ComputeHeatFluxTally::pair_tally_callback(int i, int j, int nlocal, int newton, double evdwl, double ecoul, double fpair, double dx, double dy, double dz) { const int * const mask = atom->mask; if ( ((mask[i] & groupbit) && (mask[j] & groupbit2)) || ((mask[i] & groupbit2) && (mask[j] & groupbit)) ) { const double epairhalf = 0.5 * (evdwl + ecoul); fpair *= 0.5; const double v0 = dx*dx*fpair; // dx*fpair = Fij_x const double v1 = dy*dy*fpair; const double v2 = dz*dz*fpair; const double v3 = dx*dy*fpair; const double v4 = dx*dz*fpair; const double v5 = dy*dz*fpair; if (newton || i < nlocal) { eatom[i] += epairhalf; stress[i][0] += v0; stress[i][1] += v1; stress[i][2] += v2; stress[i][3] += v3; stress[i][4] += v4; stress[i][5] += v5; } if (newton || j < nlocal) { eatom[j] += epairhalf; stress[j][0] += v0; stress[j][1] += v1; stress[j][2] += v2; stress[j][3] += v3; stress[j][4] += v4; stress[j][5] += v5; } } } /* ---------------------------------------------------------------------- */ int ComputeHeatFluxTally::pack_reverse_comm(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) { buf[m++] = eatom[i]; buf[m++] = stress[i][0]; buf[m++] = stress[i][1]; buf[m++] = stress[i][2]; buf[m++] = stress[i][3]; buf[m++] = stress[i][4]; buf[m++] = stress[i][5]; } return m; } /* ---------------------------------------------------------------------- */ void ComputeHeatFluxTally::unpack_reverse_comm(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; eatom[j] += buf[m++]; stress[j][0] += buf[m++]; stress[j][1] += buf[m++]; stress[j][2] += buf[m++]; stress[j][3] += buf[m++]; stress[j][4] += buf[m++]; stress[j][5] += buf[m++]; } } /* ---------------------------------------------------------------------- */ void ComputeHeatFluxTally::compute_vector() { invoked_vector = update->ntimestep; if ((did_setup != invoked_vector) || (update->eflag_global != invoked_vector)) error->all(FLERR,"Energy was not tallied on needed timestep"); // collect contributions from ghost atoms if (force->newton_pair) { comm->reverse_comm_compute(this); const int nall = atom->nlocal + atom->nghost; for (int i = atom->nlocal; i < nall; ++i) { eatom[i] = 0.0; stress[i][0] = 0.0; stress[i][1] = 0.0; stress[i][2] = 0.0; stress[i][3] = 0.0; stress[i][4] = 0.0; stress[i][5] = 0.0; } } // compute heat currents // heat flux vector = jc[3] + jv[3] // jc[3] = convective portion of heat flux = sum_i (ke_i + pe_i) v_i[3] // jv[3] = virial portion of heat flux = sum_i (stress_tensor_i . v_i[3]) // normalization by volume is not included // J = sum_i( (0.5*m*v_i^2 + 0.5*(evdwl_i+ecoul_i))*v_i + // + (F_ij . v_i)*dR_ij/2 ) int nlocal = atom->nlocal; int *mask = atom->mask; const double pfactor = 0.5 * force->mvv2e; double **v = atom->v; double *mass = atom->mass; double *rmass = atom->rmass; int *type = atom->type; double jc[3] = {0.0,0.0,0.0}; double jv[3] = {0.0,0.0,0.0}; for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { const double * const vi = v[i]; const double * const si = stress[i]; double ke_i; if (rmass) ke_i = pfactor * rmass[i]; - else ke_i *= pfactor * mass[type[i]]; + else ke_i = pfactor * mass[type[i]]; ke_i *= (vi[0]*vi[0] + vi[1]*vi[1] + vi[2]*vi[2]); ke_i += eatom[i]; jc[0] += ke_i*vi[0]; jc[1] += ke_i*vi[1]; jc[2] += ke_i*vi[2]; jv[0] += si[0]*vi[0] + si[3]*vi[1] + si[4]*vi[2]; jv[1] += si[3]*vi[0] + si[1]*vi[1] + si[5]*vi[2]; jv[2] += si[4]*vi[0] + si[5]*vi[1] + si[2]*vi[2]; } } // sum accumulated heatj across procs heatj[0] = jc[0] + jv[0]; heatj[1] = jc[1] + jv[1]; heatj[2] = jc[2] + jv[2]; heatj[3] = jc[0]; heatj[4] = jc[1]; heatj[5] = jc[2]; MPI_Allreduce(heatj,vector,size_vector,MPI_DOUBLE,MPI_SUM,world); } /* ---------------------------------------------------------------------- memory usage of local atom-based array ------------------------------------------------------------------------- */ double ComputeHeatFluxTally::memory_usage() { double bytes = nmax*comm_reverse * sizeof(double); return bytes; } diff --git a/src/USER-VTK/dump_vtk.h b/src/USER-VTK/dump_vtk.h index 603ca114b..8df14c7f3 100644 --- a/src/USER-VTK/dump_vtk.h +++ b/src/USER-VTK/dump_vtk.h @@ -1,321 +1,321 @@ -/* ---------------------------------------------------------------------- +/* -*- 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. This file initially came from LIGGGHTS (www.liggghts.com) Copyright (2014) DCS Computing GmbH, Linz Copyright (2015) Johannes Kepler University Linz See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ #ifdef DUMP_CLASS DumpStyle(vtk,DumpVTK) #else #ifndef LMP_DUMP_VTK_H #define LMP_DUMP_VTK_H #include "dump_custom.h" #include #include #include #include #include #include class vtkAbstractArray; class vtkRectilinearGrid; class vtkUnstructuredGrid; namespace LAMMPS_NS { /** * @brief DumpVTK class * write atom data to vtk files. * * Similar to the DumpCustom class but uses the vtk library to write data to vtk simple * legacy or xml format depending on the filename extension specified. (Since this * conflicts with the way binary output is specified, dump_modify allows to set the * binary flag for this dump command explicitly). * In contrast to DumpCustom class the attributes to be packed are stored in a std::map * to avoid duplicate entries and enforce correct ordering of vector components (except * for computes and fixes - these have to be given in the right order in the input script). * (Note: std::map elements are sorted by their keys.) * This dump command does not support compressed files, buffering or custom format strings, * multiproc is only supported by the xml formats, multifile option has to be used. */ class DumpVTK : public DumpCustom { public: DumpVTK(class LAMMPS *, int, char **); virtual ~DumpVTK(); virtual void write(); protected: char *label; // string for dump file header int vtk_file_format; // which vtk file format to write (vtk, vtp, vtu ...) std::map field2index; // which compute,fix,variable calcs this field std::map argindex; // index into compute,fix scalar_atom,vector_atom // 0 for scalar_atom, 1-N for vector_atom values // private methods virtual void init_style(); virtual void write_header(bigint); int count(); void pack(tagint *); virtual void write_data(int, double *); bigint memory_usage(); int parse_fields(int, char **); void identify_vectors(); int add_compute(char *); int add_fix(char *); int add_variable(char *); int add_custom(char *, int); virtual int modify_param(int, char **); typedef void (DumpVTK::*FnPtrHeader)(bigint); FnPtrHeader header_choice; // ptr to write header functions void header_vtk(bigint); typedef void (DumpVTK::*FnPtrWrite)(int, double *); FnPtrWrite write_choice; // ptr to write data functions void write_vtk(int, double *); void write_vtp(int, double *); void write_vtu(int, double *); void prepare_domain_data(vtkRectilinearGrid *); void prepare_domain_data_triclinic(vtkUnstructuredGrid *); void write_domain_vtk(); void write_domain_vtk_triclinic(); void write_domain_vtr(); void write_domain_vtu_triclinic(); typedef void (DumpVTK::*FnPtrPack)(int); std::map pack_choice; // ptrs to pack functions std::map vtype; // data type std::map name; // attribute labels std::set vector_set; // set of vector attributes int current_pack_choice_key; // vtk data containers vtkSmartPointer points; vtkSmartPointer pointsCells; std::map > myarrays; int n_calls_; double (*boxcorners)[3]; // corners of triclinic domain box char *filecurrent; char *domainfilecurrent; char *parallelfilecurrent; char *multiname_ex; void setFileCurrent(); void buf2arrays(int, double *); // transfer data from buf array to vtk arrays void reset_vtk_data_containers(); // customize by adding a method prototype void pack_compute(int); void pack_fix(int); void pack_variable(int); void pack_custom(int); }; } #endif #endif /* ERROR/WARNING messages: E: No dump custom arguments specified The dump custom command requires that atom quantities be specified to output to dump file. E: Invalid attribute in dump custom command Self-explanatory. E: Dump_modify format string is too short There are more fields to be dumped in a line of output than your format string specifies. E: Could not find dump custom compute ID Self-explanatory. E: Could not find dump custom fix ID Self-explanatory. E: Dump custom and fix not computed at compatible times The fix must produce per-atom quantities on timesteps that dump custom needs them. E: Could not find dump custom variable name Self-explanatory. E: Could not find custom per-atom property ID Self-explanatory. E: Region ID for dump custom does not exist Self-explanatory. E: Compute used in dump between runs is not current The compute was not invoked on the current timestep, therefore it cannot be used in a dump between runs. E: Threshhold for an atom property that isn't allocated A dump threshold has been requested on a quantity that is not defined by the atom style used in this simulation. E: Dumping an atom property that isn't allocated The chosen atom style does not define the per-atom quantity being dumped. E: Dump custom compute does not compute per-atom info Self-explanatory. E: Dump custom compute does not calculate per-atom vector Self-explanatory. E: Dump custom compute does not calculate per-atom array Self-explanatory. E: Dump custom compute vector is accessed out-of-range Self-explanatory. E: Dump custom fix does not compute per-atom info Self-explanatory. E: Dump custom fix does not compute per-atom vector Self-explanatory. E: Dump custom fix does not compute per-atom array Self-explanatory. E: Dump custom fix vector is accessed out-of-range Self-explanatory. E: Dump custom variable is not atom-style variable Only atom-style variables generate per-atom quantities, needed for dump output. E: Custom per-atom property ID is not floating point Self-explanatory. E: Custom per-atom property ID is not integer 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: Dump_modify region ID does not exist Self-explanatory. E: Dump modify element names do not match atom types Number of element names must equal number of atom types. E: Invalid attribute in dump modify command Self-explanatory. E: Could not find dump modify compute ID Self-explanatory. E: Dump modify compute ID does not compute per-atom info Self-explanatory. E: Dump modify compute ID does not compute per-atom vector Self-explanatory. E: Dump modify compute ID does not compute per-atom array Self-explanatory. E: Dump modify compute ID vector is not large enough Self-explanatory. E: Could not find dump modify fix ID Self-explanatory. E: Dump modify fix ID does not compute per-atom info Self-explanatory. E: Dump modify fix ID does not compute per-atom vector Self-explanatory. E: Dump modify fix ID does not compute per-atom array Self-explanatory. E: Dump modify fix ID vector is not large enough Self-explanatory. E: Could not find dump modify variable name Self-explanatory. E: Dump modify variable is not atom-style variable Self-explanatory. E: Could not find dump modify custom atom floating point property ID Self-explanatory. E: Could not find dump modify custom atom integer property ID Self-explanatory. E: Invalid dump_modify threshold operator Operator keyword used for threshold specification in not recognized. */ diff --git a/src/compute_cna_atom.cpp b/src/compute_cna_atom.cpp index 9680921e5..bd24e06ca 100644 --- a/src/compute_cna_atom.cpp +++ b/src/compute_cna_atom.cpp @@ -1,365 +1,365 @@ /* ---------------------------------------------------------------------- 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: Wan Liang (Chinese Academy of Sciences) ------------------------------------------------------------------------- */ #include #include #include "compute_cna_atom.h" #include "atom.h" #include "update.h" #include "force.h" #include "pair.h" #include "modify.h" #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" #include "comm.h" #include "memory.h" #include "error.h" #include using namespace LAMMPS_NS; #define MAXNEAR 16 #define MAXCOMMON 8 enum{UNKNOWN,FCC,HCP,BCC,ICOS,OTHER}; enum{NCOMMON,NBOND,MAXBOND,MINBOND}; /* ---------------------------------------------------------------------- */ ComputeCNAAtom::ComputeCNAAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg), - nearest(NULL), nnearest(NULL), pattern(NULL) + list(NULL), nearest(NULL), nnearest(NULL), pattern(NULL) { if (narg != 4) error->all(FLERR,"Illegal compute cna/atom command"); peratom_flag = 1; size_peratom_cols = 0; double cutoff = force->numeric(FLERR,arg[3]); if (cutoff < 0.0) error->all(FLERR,"Illegal compute cna/atom command"); cutsq = cutoff*cutoff; nmax = 0; } /* ---------------------------------------------------------------------- */ ComputeCNAAtom::~ComputeCNAAtom() { memory->destroy(nearest); memory->destroy(nnearest); memory->destroy(pattern); } /* ---------------------------------------------------------------------- */ void ComputeCNAAtom::init() { if (force->pair == NULL) error->all(FLERR,"Compute cna/atom requires a pair style be defined"); if (sqrt(cutsq) > force->pair->cutforce) error->all(FLERR,"Compute cna/atom cutoff is longer than pairwise cutoff"); // cannot use neighbor->cutneighmax b/c neighbor has not yet been init if (2.0*sqrt(cutsq) > force->pair->cutforce + neighbor->skin && comm->me == 0) error->warning(FLERR,"Compute cna/atom cutoff may be too large to find " "ghost atom neighbors"); int count = 0; for (int i = 0; i < modify->ncompute; i++) if (strcmp(modify->compute[i]->style,"cna/atom") == 0) count++; if (count > 1 && comm->me == 0) error->warning(FLERR,"More than one compute cna/atom defined"); // need an occasional full neighbor list int irequest = neighbor->request(this,instance_me); neighbor->requests[irequest]->pair = 0; neighbor->requests[irequest]->compute = 1; neighbor->requests[irequest]->half = 0; neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->occasional = 1; } /* ---------------------------------------------------------------------- */ void ComputeCNAAtom::init_list(int id, NeighList *ptr) { list = ptr; } /* ---------------------------------------------------------------------- */ void ComputeCNAAtom::compute_peratom() { int i,j,k,ii,jj,kk,m,n,inum,jnum,inear,jnear; int firstflag,ncommon,nbonds,maxbonds,minbonds; int nfcc,nhcp,nbcc4,nbcc6,nico,cj,ck,cl,cm; int *ilist,*jlist,*numneigh,**firstneigh; int cna[MAXNEAR][4],onenearest[MAXNEAR]; int common[MAXCOMMON],bonds[MAXCOMMON]; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; invoked_peratom = update->ntimestep; // grow arrays if necessary if (atom->nmax > nmax) { memory->destroy(nearest); memory->destroy(nnearest); memory->destroy(pattern); nmax = atom->nmax; memory->create(nearest,nmax,MAXNEAR,"cna:nearest"); memory->create(nnearest,nmax,"cna:nnearest"); memory->create(pattern,nmax,"cna:cna_pattern"); vector_atom = pattern; } // invoke full neighbor list (will copy or build if necessary) neighbor->build_one(list); inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; // find the neigbours of each atom within cutoff using full neighbor list // nearest[] = atom indices of nearest neighbors, up to MAXNEAR // do this for all atoms, not just compute group // since CNA calculation requires neighbors of neighbors double **x = atom->x; int *mask = atom->mask; int nlocal = atom->nlocal; int nerror = 0; for (ii = 0; ii < inum; ii++) { i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; jlist = firstneigh[i]; jnum = numneigh[i]; n = 0; 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; if (rsq < cutsq) { if (n < MAXNEAR) nearest[i][n++] = j; else { nerror++; break; } } } nnearest[i] = n; } // warning message int nerrorall; MPI_Allreduce(&nerror,&nerrorall,1,MPI_INT,MPI_SUM,world); if (nerrorall && comm->me == 0) { char str[128]; sprintf(str,"Too many neighbors in CNA for %d atoms",nerrorall); error->warning(FLERR,str,0); } // compute CNA for each atom in group // only performed if # of nearest neighbors = 12 or 14 (fcc,hcp) nerror = 0; for (ii = 0; ii < inum; ii++) { i = ilist[ii]; if (!(mask[i] & groupbit)) { pattern[i] = UNKNOWN; continue; } if (nnearest[i] != 12 && nnearest[i] != 14) { pattern[i] = OTHER; continue; } // loop over near neighbors of I to build cna data structure // cna[k][NCOMMON] = # of common neighbors of I with each of its neighs // cna[k][NBONDS] = # of bonds between those common neighbors // cna[k][MAXBOND] = max # of bonds of any common neighbor // cna[k][MINBOND] = min # of bonds of any common neighbor for (m = 0; m < nnearest[i]; m++) { j = nearest[i][m]; // common = list of neighbors common to atom I and atom J // if J is an owned atom, use its near neighbor list to find them // if J is a ghost atom, use full neighbor list of I to find them // in latter case, must exclude J from I's neighbor list if (j < nlocal) { firstflag = 1; ncommon = 0; for (inear = 0; inear < nnearest[i]; inear++) for (jnear = 0; jnear < nnearest[j]; jnear++) if (nearest[i][inear] == nearest[j][jnear]) { if (ncommon < MAXCOMMON) common[ncommon++] = nearest[i][inear]; else if (firstflag) { nerror++; firstflag = 0; } } } else { xtmp = x[j][0]; ytmp = x[j][1]; ztmp = x[j][2]; jlist = firstneigh[i]; jnum = numneigh[i]; n = 0; for (kk = 0; kk < jnum; kk++) { k = jlist[kk]; k &= NEIGHMASK; if (k == j) continue; delx = xtmp - x[k][0]; dely = ytmp - x[k][1]; delz = ztmp - x[k][2]; rsq = delx*delx + dely*dely + delz*delz; if (rsq < cutsq) { if (n < MAXNEAR) onenearest[n++] = k; else break; } } firstflag = 1; ncommon = 0; for (inear = 0; inear < nnearest[i]; inear++) for (jnear = 0; (jnear < n) && (n < MAXNEAR); jnear++) if (nearest[i][inear] == onenearest[jnear]) { if (ncommon < MAXCOMMON) common[ncommon++] = nearest[i][inear]; else if (firstflag) { nerror++; firstflag = 0; } } } cna[m][NCOMMON] = ncommon; // calculate total # of bonds between common neighbor atoms // also max and min # of common atoms any common atom is bonded to // bond = pair of atoms within cutoff for (n = 0; n < ncommon; n++) bonds[n] = 0; nbonds = 0; for (jj = 0; jj < ncommon-1; jj++) { j = common[jj]; xtmp = x[j][0]; ytmp = x[j][1]; ztmp = x[j][2]; for (kk = jj+1; kk < ncommon; kk++) { k = common[kk]; delx = xtmp - x[k][0]; dely = ytmp - x[k][1]; delz = ztmp - x[k][2]; rsq = delx*delx + dely*dely + delz*delz; if (rsq < cutsq) { nbonds++; bonds[jj]++; bonds[kk]++; } } } cna[m][NBOND] = nbonds; maxbonds = 0; minbonds = MAXCOMMON; for (n = 0; n < ncommon; n++) { maxbonds = MAX(bonds[n],maxbonds); minbonds = MIN(bonds[n],minbonds); } cna[m][MAXBOND] = maxbonds; cna[m][MINBOND] = minbonds; } // detect CNA pattern of the atom nfcc = nhcp = nbcc4 = nbcc6 = nico = 0; pattern[i] = OTHER; if (nnearest[i] == 12) { for (inear = 0; inear < 12; inear++) { cj = cna[inear][NCOMMON]; ck = cna[inear][NBOND]; cl = cna[inear][MAXBOND]; cm = cna[inear][MINBOND]; if (cj == 4 && ck == 2 && cl == 1 && cm == 1) nfcc++; else if (cj == 4 && ck == 2 && cl == 2 && cm == 0) nhcp++; else if (cj == 5 && ck == 5 && cl == 2 && cm == 2) nico++; } if (nfcc == 12) pattern[i] = FCC; else if (nfcc == 6 && nhcp == 6) pattern[i] = HCP; else if (nico == 12) pattern[i] = ICOS; } else if (nnearest[i] == 14) { for (inear = 0; inear < 14; inear++) { cj = cna[inear][NCOMMON]; ck = cna[inear][NBOND]; cl = cna[inear][MAXBOND]; cm = cna[inear][MINBOND]; if (cj == 4 && ck == 4 && cl == 2 && cm == 2) nbcc4++; else if (cj == 6 && ck == 6 && cl == 2 && cm == 2) nbcc6++; } if (nbcc4 == 6 && nbcc6 == 8) pattern[i] = BCC; } } // warning message MPI_Allreduce(&nerror,&nerrorall,1,MPI_INT,MPI_SUM,world); if (nerrorall && comm->me == 0) { char str[128]; sprintf(str,"Too many common neighbors in CNA %d times",nerrorall); error->warning(FLERR,str); } } /* ---------------------------------------------------------------------- memory usage of local atom-based array ------------------------------------------------------------------------- */ double ComputeCNAAtom::memory_usage() { double bytes = nmax * sizeof(int); bytes += nmax * MAXNEAR * sizeof(int); bytes += nmax * sizeof(double); return bytes; } diff --git a/src/compute_pair_local.cpp b/src/compute_pair_local.cpp index 459517550..adac486be 100644 --- a/src/compute_pair_local.cpp +++ b/src/compute_pair_local.cpp @@ -1,323 +1,327 @@ /* ---------------------------------------------------------------------- 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 "compute_pair_local.h" #include "atom.h" #include "update.h" #include "force.h" #include "pair.h" #include "neighbor.h" #include "neigh_request.h" #include "neigh_list.h" #include "group.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; #define DELTA 10000 enum{DIST,ENG,FORCE,FX,FY,FZ,PN}; enum{TYPE,RADIUS}; /* ---------------------------------------------------------------------- */ ComputePairLocal::ComputePairLocal(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg), pstyle(NULL), pindex(NULL), vlocal(NULL), alocal(NULL) { if (narg < 4) error->all(FLERR,"Illegal compute pair/local command"); local_flag = 1; nvalues = narg - 3; if (nvalues == 1) size_local_cols = 0; else size_local_cols = nvalues; pstyle = new int[nvalues]; pindex = new int[nvalues]; nvalues = 0; int iarg = 3; while (iarg < narg) { if (strcmp(arg[iarg],"dist") == 0) pstyle[nvalues++] = DIST; else if (strcmp(arg[iarg],"eng") == 0) pstyle[nvalues++] = ENG; else if (strcmp(arg[iarg],"force") == 0) pstyle[nvalues++] = FORCE; else if (strcmp(arg[iarg],"fx") == 0) pstyle[nvalues++] = FX; else if (strcmp(arg[iarg],"fy") == 0) pstyle[nvalues++] = FY; else if (strcmp(arg[iarg],"fz") == 0) pstyle[nvalues++] = FZ; else if (arg[iarg][0] == 'p') { int n = atoi(&arg[iarg][1]); if (n <= 0) error->all(FLERR, "Invalid keyword in compute pair/local command"); pstyle[nvalues] = PN; pindex[nvalues++] = n-1; } else break; iarg++; } // optional args cutstyle = TYPE; while (iarg < narg) { if (strcmp(arg[iarg],"cutoff") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal compute pair/local command"); if (strcmp(arg[iarg+1],"type") == 0) cutstyle = TYPE; else if (strcmp(arg[iarg+1],"radius") == 0) cutstyle = RADIUS; else error->all(FLERR,"Illegal compute pair/local command"); iarg += 2; } else error->all(FLERR,"Illegal compute pair/local command"); } // error check if (cutstyle == RADIUS && !atom->radius_flag) error->all(FLERR,"Compute pair/local requires atom attribute radius"); // set singleflag if need to call pair->single() singleflag = 0; for (int i = 0; i < nvalues; i++) if (pstyle[i] != DIST) singleflag = 1; nmax = 0; vlocal = NULL; alocal = NULL; } /* ---------------------------------------------------------------------- */ ComputePairLocal::~ComputePairLocal() { memory->destroy(vlocal); memory->destroy(alocal); delete [] pstyle; delete [] pindex; } /* ---------------------------------------------------------------------- */ void ComputePairLocal::init() { if (singleflag && force->pair == NULL) error->all(FLERR,"No pair style is defined for compute pair/local"); if (singleflag && force->pair->single_enable == 0) error->all(FLERR,"Pair style does not support compute pair/local"); for (int i = 0; i < nvalues; i++) if (pstyle[i] == PN && pindex[i] >= force->pair->single_extra) error->all(FLERR,"Pair style does not have extra field" " requested by compute pair/local"); // need an occasional half neighbor list + // set size to same value as request made by force->pair + // this should enable it to always be a copy list (e.g. for granular pstyle) int irequest = neighbor->request(this,instance_me); neighbor->requests[irequest]->pair = 0; neighbor->requests[irequest]->compute = 1; neighbor->requests[irequest]->occasional = 1; + NeighRequest *pairrequest = neighbor->find_request((void *) force->pair); + if (pairrequest) neighbor->requests[irequest]->size = pairrequest->size; } /* ---------------------------------------------------------------------- */ void ComputePairLocal::init_list(int id, NeighList *ptr) { list = ptr; } /* ---------------------------------------------------------------------- */ void ComputePairLocal::compute_local() { invoked_local = update->ntimestep; // count local entries and compute pair info ncount = compute_pairs(0); if (ncount > nmax) reallocate(ncount); size_local_rows = ncount; compute_pairs(1); } /* ---------------------------------------------------------------------- count pairs and compute pair info on this proc only count pair once if newton_pair is off both atom I,J must be in group if flag is set, compute requested info about pair ------------------------------------------------------------------------- */ int ComputePairLocal::compute_pairs(int flag) { int i,j,m,n,ii,jj,inum,jnum,itype,jtype; tagint itag,jtag; double xtmp,ytmp,ztmp,delx,dely,delz; double rsq,radsum,eng,fpair,factor_coul,factor_lj; int *ilist,*jlist,*numneigh,**firstneigh; double *ptr; double **x = atom->x; double *radius = atom->radius; tagint *tag = atom->tag; int *type = atom->type; int *mask = atom->mask; int nlocal = atom->nlocal; double *special_coul = force->special_coul; double *special_lj = force->special_lj; int newton_pair = force->newton_pair; // invoke half neighbor list (will copy or build if necessary) if (flag == 0) neighbor->build_one(list); inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; // loop over neighbors of my atoms // skip if I or J are not in group // for newton = 0 and J = ghost atom, // need to insure I,J pair is only output by one proc // use same itag,jtag logic as in Neighbor::neigh_half_nsq() // for flag = 0, just count pair interactions within force cutoff // for flag = 1, calculate requested output fields Pair *pair = force->pair; double **cutsq = force->pair->cutsq; m = 0; for (ii = 0; ii < inum; ii++) { i = ilist[ii]; if (!(mask[i] & groupbit)) continue; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itag = tag[i]; itype = type[i]; jlist = firstneigh[i]; jnum = numneigh[i]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; factor_lj = special_lj[sbmask(j)]; factor_coul = special_coul[sbmask(j)]; j &= NEIGHMASK; if (!(mask[j] & groupbit)) continue; // itag = jtag is possible for long cutoffs that include images of self if (newton_pair == 0 && j >= nlocal) { 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) { if (x[j][1] < ytmp) continue; if (x[j][1] == ytmp && x[j][0] < xtmp) continue; } } } 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 (cutstyle == TYPE) { if (rsq >= cutsq[itype][jtype]) continue; } else { radsum = radius[i] + radius[j]; if (rsq >= radsum*radsum) continue; } if (flag) { if (singleflag) eng = pair->single(i,j,itype,jtype,rsq,factor_coul,factor_lj,fpair); else eng = fpair = 0.0; if (nvalues == 1) ptr = &vlocal[m]; else ptr = alocal[m]; for (n = 0; n < nvalues; n++) { switch (pstyle[n]) { case DIST: ptr[n] = sqrt(rsq); break; case ENG: ptr[n] = eng; break; case FORCE: ptr[n] = sqrt(rsq)*fpair; break; case FX: ptr[n] = delx*fpair; break; case FY: ptr[n] = dely*fpair; break; case FZ: ptr[n] = delz*fpair; break; case PN: ptr[n] = pair->svector[pindex[n]]; break; } } } m++; } } return m; } /* ---------------------------------------------------------------------- */ void ComputePairLocal::reallocate(int n) { // grow vector_local or array_local while (nmax < n) nmax += DELTA; if (nvalues == 1) { memory->destroy(vlocal); memory->create(vlocal,nmax,"pair/local:vector_local"); vector_local = vlocal; } else { memory->destroy(alocal); memory->create(alocal,nmax,nvalues,"pair/local:array_local"); array_local = alocal; } } /* ---------------------------------------------------------------------- memory usage of local data ------------------------------------------------------------------------- */ double ComputePairLocal::memory_usage() { double bytes = nmax*nvalues * sizeof(double); return bytes; } diff --git a/src/compute_property_local.cpp b/src/compute_property_local.cpp index 90faa8892..27b31979c 100644 --- a/src/compute_property_local.cpp +++ b/src/compute_property_local.cpp @@ -1,968 +1,972 @@ /* ---------------------------------------------------------------------- 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 "compute_property_local.h" #include "atom.h" #include "atom_vec.h" #include "update.h" #include "force.h" #include "pair.h" #include "neighbor.h" #include "neigh_request.h" #include "neigh_list.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; enum{NONE,NEIGH,PAIR,BOND,ANGLE,DIHEDRAL,IMPROPER}; enum{TYPE,RADIUS}; #define DELTA 10000 /* ---------------------------------------------------------------------- */ ComputePropertyLocal::ComputePropertyLocal(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg), vlocal(NULL), alocal(NULL), indices(NULL), pack_choice(NULL) { if (narg < 4) error->all(FLERR,"Illegal compute property/local command"); local_flag = 1; nvalues = narg - 3; pack_choice = new FnPtrPack[nvalues]; kindflag = NONE; int i; nvalues = 0; int iarg = 3; while (iarg < narg) { i = iarg-3; if (strcmp(arg[iarg],"natom1") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_patom1; if (kindflag != NONE && kindflag != NEIGH) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = NEIGH; } else if (strcmp(arg[iarg],"natom2") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_patom2; if (kindflag != NONE && kindflag != NEIGH) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = NEIGH; } else if (strcmp(arg[iarg],"ntype1") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_ptype1; if (kindflag != NONE && kindflag != NEIGH) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = NEIGH; } else if (strcmp(arg[iarg],"ntype2") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_ptype2; if (kindflag != NONE && kindflag != NEIGH) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = NEIGH; } else if (strcmp(arg[iarg],"patom1") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_patom1; if (kindflag != NONE && kindflag != PAIR) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = PAIR; } else if (strcmp(arg[iarg],"patom2") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_patom2; if (kindflag != NONE && kindflag != PAIR) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = PAIR; } else if (strcmp(arg[iarg],"ptype1") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_ptype1; if (kindflag != NONE && kindflag != PAIR) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = PAIR; } else if (strcmp(arg[iarg],"ptype2") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_ptype2; if (kindflag != NONE && kindflag != PAIR) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = PAIR; } else if (strcmp(arg[iarg],"batom1") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_batom1; if (kindflag != NONE && kindflag != BOND) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = BOND; } else if (strcmp(arg[iarg],"batom2") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_batom2; if (kindflag != NONE && kindflag != BOND) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = BOND; } else if (strcmp(arg[iarg],"btype") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_btype; if (kindflag != NONE && kindflag != BOND) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = BOND; } else if (strcmp(arg[iarg],"aatom1") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_aatom1; if (kindflag != NONE && kindflag != ANGLE) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = ANGLE; } else if (strcmp(arg[iarg],"aatom2") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_aatom2; if (kindflag != NONE && kindflag != ANGLE) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = ANGLE; } else if (strcmp(arg[iarg],"aatom3") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_aatom3; if (kindflag != NONE && kindflag != ANGLE) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = ANGLE; } else if (strcmp(arg[iarg],"atype") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_atype; if (kindflag != NONE && kindflag != ANGLE) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = ANGLE; } else if (strcmp(arg[iarg],"datom1") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_datom1; if (kindflag != NONE && kindflag != DIHEDRAL) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = DIHEDRAL; } else if (strcmp(arg[iarg],"datom2") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_datom2; if (kindflag != NONE && kindflag != DIHEDRAL) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = DIHEDRAL; } else if (strcmp(arg[iarg],"datom3") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_datom3; if (kindflag != NONE && kindflag != DIHEDRAL) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = DIHEDRAL; } else if (strcmp(arg[iarg],"datom4") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_datom4; if (kindflag != NONE && kindflag != DIHEDRAL) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = DIHEDRAL; } else if (strcmp(arg[iarg],"dtype") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_dtype; if (kindflag != NONE && kindflag != DIHEDRAL) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = DIHEDRAL; } else if (strcmp(arg[iarg],"iatom1") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_iatom1; if (kindflag != NONE && kindflag != IMPROPER) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = IMPROPER; } else if (strcmp(arg[iarg],"iatom2") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_iatom2; if (kindflag != NONE && kindflag != IMPROPER) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = IMPROPER; } else if (strcmp(arg[iarg],"iatom3") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_iatom3; if (kindflag != NONE && kindflag != IMPROPER) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = IMPROPER; } else if (strcmp(arg[iarg],"iatom4") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_iatom4; if (kindflag != NONE && kindflag != IMPROPER) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = IMPROPER; } else if (strcmp(arg[iarg],"itype") == 0) { pack_choice[i] = &ComputePropertyLocal::pack_itype; if (kindflag != NONE && kindflag != IMPROPER) error->all(FLERR, "Compute property/local cannot use these inputs together"); kindflag = IMPROPER; } else break; nvalues++; iarg++; } if (nvalues == 1) size_local_cols = 0; else size_local_cols = nvalues; // optional args cutstyle = TYPE; while (iarg < narg) { if (strcmp(arg[iarg],"cutoff") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal compute property/local command"); if (strcmp(arg[iarg+1],"type") == 0) cutstyle = TYPE; else if (strcmp(arg[iarg+1],"radius") == 0) cutstyle = RADIUS; else error->all(FLERR,"Illegal compute property/local command"); iarg += 2; } else error->all(FLERR,"Illegal compute property/local command"); } // error check if (atom->molecular == 2 && (kindflag == BOND || kindflag == ANGLE || kindflag == DIHEDRAL || kindflag == IMPROPER)) error->all(FLERR,"Compute property/local does not (yet) work " "with atom_style template"); if (kindflag == BOND && atom->avec->bonds_allow == 0) error->all(FLERR, "Compute property/local for property that isn't allocated"); if (kindflag == ANGLE && atom->avec->angles_allow == 0) error->all(FLERR, "Compute property/local for property that isn't allocated"); if (kindflag == DIHEDRAL && atom->avec->dihedrals_allow == 0) error->all(FLERR, "Compute property/local for property that isn't allocated"); if (kindflag == IMPROPER && atom->avec->impropers_allow == 0) error->all(FLERR, "Compute property/local for property that isn't allocated"); if (cutstyle == RADIUS && !atom->radius_flag) error->all(FLERR,"Compute property/local requires atom attribute radius"); nmax = 0; vlocal = NULL; alocal = NULL; } /* ---------------------------------------------------------------------- */ ComputePropertyLocal::~ComputePropertyLocal() { delete [] pack_choice; memory->destroy(vlocal); memory->destroy(alocal); memory->destroy(indices); } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::init() { if (kindflag == NEIGH || kindflag == PAIR) { if (force->pair == NULL) error->all(FLERR,"No pair style is defined for compute property/local"); if (force->pair->single_enable == 0) error->all(FLERR,"Pair style does not support compute property/local"); } // for NEIGH/PAIR need an occasional half neighbor list + // set size to same value as request made by force->pair + // this should enable it to always be a copy list (e.g. for granular pstyle) if (kindflag == NEIGH || kindflag == PAIR) { int irequest = neighbor->request(this,instance_me); neighbor->requests[irequest]->pair = 0; neighbor->requests[irequest]->compute = 1; neighbor->requests[irequest]->occasional = 1; + NeighRequest *pairrequest = neighbor->find_request((void *) force->pair); + if (pairrequest) neighbor->requests[irequest]->size = pairrequest->size; } // do initial memory allocation so that memory_usage() is correct // cannot be done yet for NEIGH/PAIR, since neigh list does not exist if (kindflag == NEIGH) ncount = 0; else if (kindflag == PAIR) ncount = 0; else if (kindflag == BOND) ncount = count_bonds(0); else if (kindflag == ANGLE) ncount = count_angles(0); else if (kindflag == DIHEDRAL) ncount = count_dihedrals(0); else if (kindflag == IMPROPER) ncount = count_impropers(0); if (ncount > nmax) reallocate(ncount); size_local_rows = ncount; } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::init_list(int id, NeighList *ptr) { list = ptr; } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::compute_local() { invoked_local = update->ntimestep; // count local entries and generate list of indices if (kindflag == NEIGH) ncount = count_pairs(0,0); else if (kindflag == PAIR) ncount = count_pairs(0,1); else if (kindflag == BOND) ncount = count_bonds(0); else if (kindflag == ANGLE) ncount = count_angles(0); else if (kindflag == DIHEDRAL) ncount = count_dihedrals(0); else if (kindflag == IMPROPER) ncount = count_impropers(0); if (ncount > nmax) reallocate(ncount); size_local_rows = ncount; if (kindflag == NEIGH) ncount = count_pairs(1,0); else if (kindflag == PAIR) ncount = count_pairs(1,1); else if (kindflag == BOND) ncount = count_bonds(1); else if (kindflag == ANGLE) ncount = count_angles(1); else if (kindflag == DIHEDRAL) ncount = count_dihedrals(1); else if (kindflag == IMPROPER) ncount = count_impropers(1); // fill vector or array with local values if (nvalues == 1) { buf = vlocal; (this->*pack_choice[0])(0); } else { if (alocal) buf = &alocal[0][0]; for (int n = 0; n < nvalues; n++) (this->*pack_choice[n])(n); } } /* ---------------------------------------------------------------------- count pairs and compute pair info on this proc only count pair once if newton_pair is off both atom I,J must be in group if allflag is set, compute requested info about pair if forceflag = 1, pair must be within force cutoff, else neighbor cutoff ------------------------------------------------------------------------- */ int ComputePropertyLocal::count_pairs(int allflag, int forceflag) { int i,j,m,ii,jj,inum,jnum,itype,jtype; tagint itag,jtag; double xtmp,ytmp,ztmp,delx,dely,delz,rsq,radsum; int *ilist,*jlist,*numneigh,**firstneigh; double **x = atom->x; double *radius = atom->radius; tagint *tag = atom->tag; int *type = atom->type; int *mask = atom->mask; int nlocal = atom->nlocal; int newton_pair = force->newton_pair; // invoke half neighbor list (will copy or build if necessary) if (allflag == 0) neighbor->build_one(list); inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; // loop over neighbors of my atoms // skip if I or J are not in group // for newton = 0 and J = ghost atom, // need to insure I,J pair is only output by one proc // use same itag,jtag logic as in Neighbor::neigh_half_nsq() double **cutsq = force->pair->cutsq; m = 0; for (ii = 0; ii < inum; ii++) { i = ilist[ii]; if (!(mask[i] & groupbit)) continue; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itag = tag[i]; itype = type[i]; jlist = firstneigh[i]; jnum = numneigh[i]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; j &= NEIGHMASK; if (!(mask[j] & groupbit)) continue; // itag = jtag is possible for long cutoffs that include images of self if (newton_pair == 0 && j >= nlocal) { 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) { if (x[j][1] < ytmp) continue; if (x[j][1] == ytmp && x[j][0] < xtmp) continue; } } } 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 (forceflag) { if (cutstyle == TYPE) { if (rsq >= cutsq[itype][jtype]) continue; } else { radsum = radius[i] + radius[j]; if (rsq >= radsum*radsum) continue; } } if (allflag) { indices[m][0] = i; indices[m][1] = j; } m++; } } return m; } /* ---------------------------------------------------------------------- count bonds on this proc only count bond once if newton_bond is off all atoms in interaction must be in group all atoms in interaction must be known to proc if bond is deleted (type = 0), do not count if bond is turned off (type < 0), still count ------------------------------------------------------------------------- */ int ComputePropertyLocal::count_bonds(int flag) { int i,atom1,atom2; int *num_bond = atom->num_bond; tagint **bond_atom = atom->bond_atom; int **bond_type = atom->bond_type; tagint *tag = atom->tag; int *mask = atom->mask; int nlocal = atom->nlocal; int newton_bond = force->newton_bond; int m = 0; for (atom1 = 0; atom1 < nlocal; atom1++) { if (!(mask[atom1] & groupbit)) continue; for (i = 0; i < num_bond[atom1]; i++) { atom2 = atom->map(bond_atom[atom1][i]); if (atom2 < 0 || !(mask[atom2] & groupbit)) continue; if (newton_bond == 0 && tag[atom1] > tag[atom2]) continue; if (bond_type[atom1][i] == 0) continue; if (flag) { indices[m][0] = atom1; indices[m][1] = i; } m++; } } return m; } /* ---------------------------------------------------------------------- count angles on this proc only count if 2nd atom is the one storing the angle all atoms in interaction must be in group all atoms in interaction must be known to proc if angle is deleted (type = 0), do not count if angle is turned off (type < 0), still count ------------------------------------------------------------------------- */ int ComputePropertyLocal::count_angles(int flag) { int i,atom1,atom2,atom3; int *num_angle = atom->num_angle; tagint **angle_atom1 = atom->angle_atom1; tagint **angle_atom2 = atom->angle_atom2; tagint **angle_atom3 = atom->angle_atom3; int **angle_type = atom->angle_type; tagint *tag = atom->tag; int *mask = atom->mask; int nlocal = atom->nlocal; int m = 0; for (atom2 = 0; atom2 < nlocal; atom2++) { if (!(mask[atom2] & groupbit)) continue; for (i = 0; i < num_angle[atom2]; i++) { if (tag[atom2] != angle_atom2[atom2][i]) continue; atom1 = atom->map(angle_atom1[atom2][i]); if (atom1 < 0 || !(mask[atom1] & groupbit)) continue; atom3 = atom->map(angle_atom3[atom2][i]); if (atom3 < 0 || !(mask[atom3] & groupbit)) continue; if (angle_type[atom2][i] == 0) continue; if (flag) { indices[m][0] = atom2; indices[m][1] = i; } m++; } } return m; } /* ---------------------------------------------------------------------- count dihedrals on this proc only count if 2nd atom is the one storing the dihedral all atoms in interaction must be in group all atoms in interaction must be known to proc ------------------------------------------------------------------------- */ int ComputePropertyLocal::count_dihedrals(int flag) { int i,atom1,atom2,atom3,atom4; int *num_dihedral = atom->num_dihedral; tagint **dihedral_atom1 = atom->dihedral_atom1; tagint **dihedral_atom2 = atom->dihedral_atom2; tagint **dihedral_atom3 = atom->dihedral_atom3; tagint **dihedral_atom4 = atom->dihedral_atom4; tagint *tag = atom->tag; int *mask = atom->mask; int nlocal = atom->nlocal; int m = 0; for (atom2 = 0; atom2 < nlocal; atom2++) { if (!(mask[atom2] & groupbit)) continue; for (i = 0; i < num_dihedral[atom2]; i++) { if (tag[atom2] != dihedral_atom2[atom2][i]) continue; atom1 = atom->map(dihedral_atom1[atom2][i]); if (atom1 < 0 || !(mask[atom1] & groupbit)) continue; atom3 = atom->map(dihedral_atom3[atom2][i]); if (atom3 < 0 || !(mask[atom3] & groupbit)) continue; atom4 = atom->map(dihedral_atom4[atom2][i]); if (atom4 < 0 || !(mask[atom4] & groupbit)) continue; if (flag) { indices[m][0] = atom2; indices[m][1] = i; } m++; } } return m; } /* ---------------------------------------------------------------------- count impropers on this proc only count if 2nd atom is the one storing the improper all atoms in interaction must be in group all atoms in interaction must be known to proc ------------------------------------------------------------------------- */ int ComputePropertyLocal::count_impropers(int flag) { int i,atom1,atom2,atom3,atom4; int *num_improper = atom->num_improper; tagint **improper_atom1 = atom->improper_atom1; tagint **improper_atom2 = atom->improper_atom2; tagint **improper_atom3 = atom->improper_atom3; tagint **improper_atom4 = atom->improper_atom4; tagint *tag = atom->tag; int *mask = atom->mask; int nlocal = atom->nlocal; int m = 0; for (atom2 = 0; atom2 < nlocal; atom2++) { if (!(mask[atom2] & groupbit)) continue; for (i = 0; i < num_improper[atom2]; i++) { if (tag[atom2] != improper_atom2[atom2][i]) continue; atom1 = atom->map(improper_atom1[atom2][i]); if (atom1 < 0 || !(mask[atom1] & groupbit)) continue; atom3 = atom->map(improper_atom3[atom2][i]); if (atom3 < 0 || !(mask[atom3] & groupbit)) continue; atom4 = atom->map(improper_atom4[atom2][i]); if (atom4 < 0 || !(mask[atom4] & groupbit)) continue; if (flag) { indices[m][0] = atom2; indices[m][1] = i; } m++; } } return m; } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::reallocate(int n) { // grow vector_local or array_local, also indices while (nmax < n) nmax += DELTA; if (nvalues == 1) { memory->destroy(vlocal); memory->create(vlocal,nmax,"property/local:vector_local"); vector_local = vlocal; } else { memory->destroy(alocal); memory->create(alocal,nmax,nvalues,"property/local:array_local"); array_local = alocal; } memory->destroy(indices); memory->create(indices,nmax,2,"property/local:indices"); } /* ---------------------------------------------------------------------- memory usage of local data ------------------------------------------------------------------------- */ double ComputePropertyLocal::memory_usage() { double bytes = nmax*nvalues * sizeof(double); bytes += nmax*2 * sizeof(int); return bytes; } /* ---------------------------------------------------------------------- one method for every keyword compute property/local can output the atom property is packed into buf starting at n with stride nvalues customize a new keyword by adding a method ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_patom1(int n) { int i; tagint *tag = atom->tag; for (int m = 0; m < ncount; m++) { i = indices[m][0]; buf[n] = tag[i]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_patom2(int n) { int i; tagint *tag = atom->tag; for (int m = 0; m < ncount; m++) { i = indices[m][1]; buf[n] = tag[i]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_ptype1(int n) { int i; int *type = atom->type; for (int m = 0; m < ncount; m++) { i = indices[m][0]; buf[n] = type[i]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_ptype2(int n) { int i; int *type = atom->type; for (int m = 0; m < ncount; m++) { i = indices[m][1]; buf[n] = type[i]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_batom1(int n) { int i; tagint *tag = atom->tag; for (int m = 0; m < ncount; m++) { i = indices[m][0]; buf[n] = tag[i]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_batom2(int n) { int i,j; tagint **bond_atom = atom->bond_atom; for (int m = 0; m < ncount; m++) { i = indices[m][0]; j = indices[m][1]; buf[n] = bond_atom[i][j]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_btype(int n) { int i,j; int **bond_type = atom->bond_type; for (int m = 0; m < ncount; m++) { i = indices[m][0]; j = indices[m][1]; buf[n] = bond_type[i][j]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_aatom1(int n) { int i,j; tagint **angle_atom1 = atom->angle_atom1; for (int m = 0; m < ncount; m++) { i = indices[m][0]; j = indices[m][1]; buf[n] = angle_atom1[i][j]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_aatom2(int n) { int i,j; tagint **angle_atom2 = atom->angle_atom2; for (int m = 0; m < ncount; m++) { i = indices[m][0]; j = indices[m][1]; buf[n] = angle_atom2[i][j]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_aatom3(int n) { int i,j; tagint **angle_atom3 = atom->angle_atom3; for (int m = 0; m < ncount; m++) { i = indices[m][0]; j = indices[m][1]; buf[n] = angle_atom3[i][j]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_atype(int n) { int i,j; int **angle_type = atom->angle_type; for (int m = 0; m < ncount; m++) { i = indices[m][0]; j = indices[m][1]; buf[n] = angle_type[i][j]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_datom1(int n) { int i,j; tagint **dihedral_atom1 = atom->dihedral_atom1; for (int m = 0; m < ncount; m++) { i = indices[m][0]; j = indices[m][1]; buf[n] = dihedral_atom1[i][j]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_datom2(int n) { int i,j; tagint **dihedral_atom2 = atom->dihedral_atom2; for (int m = 0; m < ncount; m++) { i = indices[m][0]; j = indices[m][1]; buf[n] = dihedral_atom2[i][j]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_datom3(int n) { int i,j; tagint **dihedral_atom3 = atom->dihedral_atom3; for (int m = 0; m < ncount; m++) { i = indices[m][0]; j = indices[m][1]; buf[n] = dihedral_atom3[i][j]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_datom4(int n) { int i,j; tagint **dihedral_atom4 = atom->dihedral_atom4; for (int m = 0; m < ncount; m++) { i = indices[m][0]; j = indices[m][1]; buf[n] = dihedral_atom4[i][j]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_dtype(int n) { int i,j; int **dihedral_type = atom->dihedral_type; for (int m = 0; m < ncount; m++) { i = indices[m][0]; j = indices[m][1]; buf[n] = dihedral_type[i][j]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_iatom1(int n) { int i,j; tagint **improper_atom1 = atom->improper_atom1; for (int m = 0; m < ncount; m++) { i = indices[m][0]; j = indices[m][1]; buf[n] = improper_atom1[i][j]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_iatom2(int n) { int i,j; tagint **improper_atom2 = atom->improper_atom2; for (int m = 0; m < ncount; m++) { i = indices[m][0]; j = indices[m][1]; buf[n] = improper_atom2[i][j]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_iatom3(int n) { int i,j; tagint **improper_atom3 = atom->improper_atom3; for (int m = 0; m < ncount; m++) { i = indices[m][0]; j = indices[m][1]; buf[n] = improper_atom3[i][j]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_iatom4(int n) { int i,j; tagint **improper_atom4 = atom->improper_atom4; for (int m = 0; m < ncount; m++) { i = indices[m][0]; j = indices[m][1]; buf[n] = improper_atom4[i][j]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyLocal::pack_itype(int n) { int i,j; int **improper_type = atom->improper_type; for (int m = 0; m < ncount; m++) { i = indices[m][0]; j = indices[m][1]; buf[n] = improper_type[i][j]; n += nvalues; } } diff --git a/src/dump.h b/src/dump.h index 3c1450854..a5582ce5a 100644 --- a/src/dump.h +++ b/src/dump.h @@ -1,214 +1,214 @@ /* -*- 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_DUMP_H #define LMP_DUMP_H #include #include #include "pointers.h" namespace LAMMPS_NS { class Dump : protected Pointers { public: char *id; // user-defined name of Dump char *style; // style of Dump char *filename; // user-specified file int igroup,groupbit; // group that Dump is performed on int first_flag; // 0 if no initial dump, 1 if yes initial dump int clearstep; // 1 if dump invokes computes, 0 if not int comm_forward; // size of forward communication (0 if none) int comm_reverse; // size of reverse communication (0 if none) -#if defined(LMP_USE_LIBC_QSORT) +#if defined(LMP_QSORT) // static variable across all Dump objects static Dump *dumpptr; // holds a ptr to Dump currently being used #endif Dump(class LAMMPS *, int, char **); virtual ~Dump(); void init(); virtual void write(); 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(int, int, double *) {return 0;} virtual void unpack_reverse_comm(int, int *, double *) {} void modify_params(int, char **); virtual bigint memory_usage(); protected: int me,nprocs; // proc info int compressed; // 1 if dump file is written compressed, 0 no int binary; // 1 if dump file is written binary, 0 no int multifile; // 0 = one big file, 1 = one file per timestep int multiproc; // 0 = proc 0 writes for all, // else # of procs writing files int nclusterprocs; // # of procs in my cluster that write to one file int filewriter; // 1 if this proc writes a file, else 0 int fileproc; // ID of proc in my cluster who writes to file char *multiname; // filename with % converted to cluster ID MPI_Comm clustercomm; // MPI communicator within my cluster of procs int header_flag; // 0 = item, 2 = xyz int flush_flag; // 0 if no flush, 1 if flush every dump int sort_flag; // 1 if sorted output int append_flag; // 1 if open file in append mode, 0 if not int buffer_allow; // 1 if style allows for buffer_flag, 0 if not int buffer_flag; // 1 if buffer output as one big string, 0 if not int padflag; // timestep padding in filename int pbcflag; // 1 if remap dumped atoms via PBC, 0 if not int singlefile_opened; // 1 = one big file, already opened, else 0 int sortcol; // 0 to sort on ID, 1-N on columns int sortcolm1; // sortcol - 1 int sortorder; // ASCEND or DESCEND char boundstr[9]; // encoding of boundary flags char *format; // format string for the file write char *format_default; // default format string char *format_line_user; // user-specified format strings char *format_float_user; char *format_int_user; char *format_bigint_user; char **format_column_user; FILE *fp; // file to write dump to int size_one; // # of quantities for one atom int nme; // # of atoms in this dump from me int nsme; // # of chars in string output from me double boxxlo,boxxhi; // local copies of domain values double boxylo,boxyhi; // lo/hi are bounding box for triclinic double boxzlo,boxzhi; double boxxy,boxxz,boxyz; bigint ntotal; // total # of per-atom lines in snapshot int reorderflag; // 1 if OK to reorder instead of sort int ntotal_reorder; // # of atoms that must be in snapshot int nme_reorder; // # of atoms I must own in snapshot tagint idlo; // lowest ID I own when reordering int maxbuf; // size of buf double *buf; // memory for atom quantities int maxsbuf; // size of sbuf char *sbuf; // memory for atom quantities in string format int maxids; // size of ids int maxsort; // size of bufsort, idsort, index int maxproc; // size of proclist tagint *ids; // list of atom IDs, if sorting on IDs double *bufsort; tagint *idsort; int *index,*proclist; double **xpbc,**vpbc; imageint *imagepbc; int maxpbc; class Irregular *irregular; virtual void init_style() = 0; virtual void openfile(); virtual int modify_param(int, char **) {return 0;} virtual void write_header(bigint) = 0; virtual int count(); virtual void pack(tagint *) = 0; virtual int convert_string(int, double *) {return 0;} virtual void write_data(int, double *) = 0; void pbc_allocate(); void sort(); -#if defined(LMP_USE_LIBC_QSORT) +#if defined(LMP_QSORT) static int idcompare(const void *, const void *); static int bufcompare(const void *, const void *); static int bufcompare_reverse(const void *, const void *); #else static int idcompare(const int, const int, void *); static int bufcompare(const int, const int, void *); static int bufcompare_reverse(const int, const int, void *); #endif }; } #endif /* ERROR/WARNING messages: E: Dump file MPI-IO output not allowed with % in filename This is because a % signifies one file per processor and MPI-IO creates one large file for all processors. E: Cannot dump sort when multiple dump files are written In this mode, each processor dumps its atoms to a file, so no sorting is allowed. E: Cannot dump sort on atom IDs with no atom IDs defined Self-explanatory. E: Dump sort column is invalid Self-explanatory. E: Too many atoms to dump sort Cannot sort when running with more than 2^31 atoms. E: Too much per-proc info for dump Number of local atoms times number of columns must fit in a 32-bit integer for dump. E: Too much buffered per-proc info for dump The size of the buffered string must fit in a 32-bit integer for a dump. E: Cannot open gzipped file LAMMPS was compiled without support for reading and writing gzipped files through a pipeline to the gzip program with -DLAMMPS_GZIP. E: Cannot open dump file 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: Dump_modify buffer yes not allowed for this style Self-explanatory. E: Cannot use dump_modify fileper without % in dump file name Self-explanatory. E: Cannot use dump_modify nfile without % in dump file name Self-explanatory. */ diff --git a/src/irregular.h b/src/irregular.h index 5b2a77184..1f74fe801 100644 --- a/src/irregular.h +++ b/src/irregular.h @@ -1,102 +1,102 @@ /* -*- 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_IRREGULAR_H #define LMP_IRREGULAR_H #include "pointers.h" namespace LAMMPS_NS { class Irregular : protected Pointers { public: -#if defined(LMP_USE_LIBC_QSORT) +#if defined(LMP_QSORT) // static variable across all Irregular objects, for qsort callback static int *proc_recv_copy; #endif Irregular(class LAMMPS *); ~Irregular(); void migrate_atoms(int sortflag = 0, int preassign = 0, int *procassign = NULL); int migrate_check(); int create_data(int, int *, int sortflag = 0); void exchange_data(char *, int, char *); void destroy_data(); bigint memory_usage(); private: int me,nprocs; int triclinic; int map_style; int maxsend,maxrecv; // size of buf send/recv in # of doubles double *buf_send,*buf_recv; // bufs used in migrate_atoms int maxdbuf; // size of double buf in bytes double *dbuf; // double buf for largest single atom send int maxbuf; // size of char buf in bytes char *buf; // char buf for largest single data send int *mproclist,*msizes; // persistent vectors in migrate_atoms int maxlocal; // allocated size of mproclist and msizes int *work1,*work2; // work vectors // plan params for irregular communication of atoms or datums // no params refer to atoms/data copied to self int nsend_proc; // # of messages to send int nrecv_proc; // # of messages to recv int sendmax_proc; // # of doubles/datums in largest send message int *proc_send; // list of procs to send to int *num_send; // # of atoms/datums to send to each proc int *index_send; // list of which atoms/datums to send to each proc int *proc_recv; // list of procs to recv from MPI_Request *request; // MPI requests for posted recvs MPI_Status *status; // MPI statuses for WaitAll // extra plan params plan for irregular communication of atoms // no params refer to atoms copied to self int *length_send; // # of doubles to send to each proc int *length_recv; // # of doubles to recv from each proc int *offset_send; // where each atom starts in send buffer // extra plan params plan for irregular communication of datums // 2 self params refer to data copied to self int *num_recv; // # of datums to recv from each proc int num_self; // # of datums to copy to self int *index_self; // list of which datums to copy to self // private methods int create_atom(int, int *, int *, int); void exchange_atom(double *, int *, double *); void destroy_atom(); int binary(double, int, double *); void grow_send(int,int); // reallocate send buffer void grow_recv(int); // free/allocate recv buffer }; } #endif /* ERROR/WARNING messages: */ diff --git a/src/neighbor.cpp b/src/neighbor.cpp index 62a914322..487b860c9 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -1,2441 +1,2462 @@ /* ---------------------------------------------------------------------- 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 (triclinic and multi-neigh) : Pieter in 't Veld (SNL) ------------------------------------------------------------------------- */ #include #include #include #include #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" #include "style_nbin.h" #include "style_nstencil.h" #include "style_npair.h" #include "style_ntopo.h" #include "atom.h" #include "atom_vec.h" #include "comm.h" #include "force.h" #include "pair.h" #include "domain.h" #include "group.h" #include "modify.h" #include "fix.h" #include "compute.h" #include "update.h" #include "respa.h" #include "output.h" #include "citeme.h" #include "memory.h" #include "error.h" #include using namespace LAMMPS_NS; using namespace NeighConst; #define RQDELTA 1 #define EXDELTA 1 #define BIG 1.0e20 enum{NSQ,BIN,MULTI}; // also in NBin, NeighList, NStencil enum{NONE,ALL,PARTIAL,TEMPLATE}; static const char cite_neigh_multi[] = "neighbor multi command:\n\n" "@Article{Intveld08,\n" " author = {P.{\\,}J.~in{\\,}'t~Veld and S.{\\,}J.~Plimpton" " and G.{\\,}S.~Grest},\n" " title = {Accurate and Efficient Methods for Modeling Colloidal\n" " Mixtures in an Explicit Solvent using Molecular Dynamics},\n" " journal = {Comp.~Phys.~Comm.},\n" " year = 2008,\n" " volume = 179,\n" " pages = {320--329}\n" "}\n\n"; //#define NEIGH_LIST_DEBUG 1 /* ---------------------------------------------------------------------- */ Neighbor::Neighbor(LAMMPS *lmp) : Pointers(lmp), pairclass(NULL), pairnames(NULL), pairmasks(NULL) { MPI_Comm_rank(world,&me); MPI_Comm_size(world,&nprocs); firsttime = 1; style = BIN; every = 1; delay = 10; dist_check = 1; pgsize = 100000; oneatom = 2000; binsizeflag = 0; build_once = 0; cluster_check = 0; ago = -1; cutneighmax = 0.0; cutneighsq = NULL; cutneighghostsq = NULL; cuttype = NULL; cuttypesq = NULL; fixchecklist = NULL; // pairwise neighbor lists and associated data structs nlist = 0; lists = NULL; nbin = 0; neigh_bin = NULL; nstencil = 0; neigh_stencil = NULL; neigh_pair = NULL; nstencil_perpetual = 0; slist = NULL; npair_perpetual = 0; plist = NULL; nrequest = maxrequest = 0; requests = NULL; old_nrequest = 0; old_requests = NULL; old_style = style; old_triclinic = 0; old_pgsize = pgsize; old_oneatom = oneatom; zeroes = NULL; binclass = NULL; binnames = NULL; binmasks = NULL; stencilclass = NULL; stencilnames = NULL; stencilmasks = NULL; // topology lists bondwhich = anglewhich = dihedralwhich = improperwhich = NONE; neigh_bond = NULL; neigh_angle = NULL; neigh_dihedral = NULL; neigh_improper = NULL; // coords at last neighboring maxhold = 0; xhold = NULL; lastcall = -1; last_setup_bins = -1; // pair exclusion list info includegroup = 0; nex_type = maxex_type = 0; ex1_type = ex2_type = NULL; ex_type = NULL; nex_group = maxex_group = 0; ex1_group = ex2_group = ex1_bit = ex2_bit = NULL; nex_mol = maxex_mol = 0; ex_mol_group = ex_mol_bit = ex_mol_intra = NULL; // Kokkos setting copymode = 0; } /* ---------------------------------------------------------------------- */ Neighbor::~Neighbor() { if (copymode) return; memory->destroy(cutneighsq); memory->destroy(cutneighghostsq); delete [] cuttype; delete [] cuttypesq; delete [] fixchecklist; for (int i = 0; i < nlist; i++) delete lists[i]; for (int i = 0; i < nbin; i++) delete neigh_bin[i]; for (int i = 0; i < nstencil; i++) delete neigh_stencil[i]; for (int i = 0; i < nlist; i++) delete neigh_pair[i]; delete [] lists; delete [] neigh_bin; delete [] neigh_stencil; delete [] neigh_pair; delete [] slist; delete [] plist; for (int i = 0; i < nlist; i++) if (requests[i]) delete requests[i]; memory->sfree(requests); for (int i = 0; i < old_nrequest; i++) if (old_requests[i]) delete old_requests[i]; memory->sfree(old_requests); delete [] zeroes; delete [] binclass; delete [] binnames; delete [] binmasks; delete [] stencilclass; delete [] stencilnames; delete [] stencilmasks; delete [] pairclass; delete [] pairnames; delete [] pairmasks; delete neigh_bond; delete neigh_angle; delete neigh_dihedral; delete neigh_improper; memory->destroy(xhold); memory->destroy(ex1_type); memory->destroy(ex2_type); memory->destroy(ex_type); memory->destroy(ex1_group); memory->destroy(ex2_group); delete [] ex1_bit; delete [] ex2_bit; memory->destroy(ex_mol_group); delete [] ex_mol_bit; memory->destroy(ex_mol_intra); } /* ---------------------------------------------------------------------- */ void Neighbor::init() { int i,j,n; ncalls = ndanger = 0; dimension = domain->dimension; triclinic = domain->triclinic; newton_pair = force->newton_pair; // error check if (delay > 0 && (delay % every) != 0) error->all(FLERR,"Neighbor delay must be 0 or multiple of every setting"); if (pgsize < 10*oneatom) error->all(FLERR,"Neighbor page size must be >= 10x the one atom setting"); // ------------------------------------------------------------------ // settings // bbox lo/hi ptrs = bounding box of entire domain, stored by Domain if (triclinic == 0) { bboxlo = domain->boxlo; bboxhi = domain->boxhi; } else { bboxlo = domain->boxlo_bound; bboxhi = domain->boxhi_bound; } // set neighbor cutoffs (force cutoff + skin) // trigger determines when atoms migrate and neighbor lists are rebuilt // needs to be non-zero for migration distance check // even if pair = NULL and no neighbor lists are used // cutneigh = force cutoff + skin if cutforce > 0, else cutneigh = 0 // cutneighghost = pair cutghost if it requests it, else same as cutneigh triggersq = 0.25*skin*skin; boxcheck = 0; if (domain->box_change && (domain->xperiodic || domain->yperiodic || (dimension == 3 && domain->zperiodic))) boxcheck = 1; n = atom->ntypes; if (cutneighsq == NULL) { if (lmp->kokkos) init_cutneighsq_kokkos(n); else memory->create(cutneighsq,n+1,n+1,"neigh:cutneighsq"); memory->create(cutneighghostsq,n+1,n+1,"neigh:cutneighghostsq"); cuttype = new double[n+1]; cuttypesq = new double[n+1]; } double cutoff,delta,cut; cutneighmin = BIG; cutneighmax = 0.0; for (i = 1; i <= n; i++) { cuttype[i] = cuttypesq[i] = 0.0; for (j = 1; j <= n; j++) { if (force->pair) cutoff = sqrt(force->pair->cutsq[i][j]); else cutoff = 0.0; if (cutoff > 0.0) delta = skin; else delta = 0.0; cut = cutoff + delta; cutneighsq[i][j] = cut*cut; cuttype[i] = MAX(cuttype[i],cut); cuttypesq[i] = MAX(cuttypesq[i],cut*cut); cutneighmin = MIN(cutneighmin,cut); cutneighmax = MAX(cutneighmax,cut); if (force->pair && force->pair->ghostneigh) { cut = force->pair->cutghost[i][j] + skin; cutneighghostsq[i][j] = cut*cut; } else cutneighghostsq[i][j] = cut*cut; } } cutneighmaxsq = cutneighmax * cutneighmax; // rRESPA cutoffs int respa = 0; if (update->whichflag == 1 && strstr(update->integrate_style,"respa")) { if (((Respa *) update->integrate)->level_inner >= 0) respa = 1; if (((Respa *) update->integrate)->level_middle >= 0) respa = 2; } if (respa) { double *cut_respa = ((Respa *) update->integrate)->cutoff; cut_inner_sq = (cut_respa[1] + skin) * (cut_respa[1] + skin); cut_middle_sq = (cut_respa[3] + skin) * (cut_respa[3] + skin); cut_middle_inside_sq = (cut_respa[0] - skin) * (cut_respa[0] - skin); if (cut_respa[0]-skin < 0) cut_middle_inside_sq = 0.0; } // fixchecklist = other classes that can induce reneighboring in decide() restart_check = 0; if (output->restart_flag) restart_check = 1; delete [] fixchecklist; fixchecklist = NULL; fixchecklist = new int[modify->nfix]; fix_check = 0; for (i = 0; i < modify->nfix; i++) if (modify->fix[i]->force_reneighbor) fixchecklist[fix_check++] = i; must_check = 0; if (restart_check || fix_check) must_check = 1; // set special_flag for 1-2, 1-3, 1-4 neighbors // flag[0] is not used, flag[1] = 1-2, flag[2] = 1-3, flag[3] = 1-4 // flag = 0 if both LJ/Coulomb special values are 0.0 // flag = 1 if both LJ/Coulomb special values are 1.0 // flag = 2 otherwise or if KSpace solver is enabled // pairwise portion of KSpace solver uses all 1-2,1-3,1-4 neighbors // or selected Coulomb-approixmation pair styles require it if (force->special_lj[1] == 0.0 && force->special_coul[1] == 0.0) special_flag[1] = 0; else if (force->special_lj[1] == 1.0 && force->special_coul[1] == 1.0) special_flag[1] = 1; else special_flag[1] = 2; if (force->special_lj[2] == 0.0 && force->special_coul[2] == 0.0) special_flag[2] = 0; else if (force->special_lj[2] == 1.0 && force->special_coul[2] == 1.0) special_flag[2] = 1; else special_flag[2] = 2; if (force->special_lj[3] == 0.0 && force->special_coul[3] == 0.0) special_flag[3] = 0; else if (force->special_lj[3] == 1.0 && force->special_coul[3] == 1.0) special_flag[3] = 1; else special_flag[3] = 2; if (force->kspace || force->pair_match("coul/wolf",0) || force->pair_match("coul/dsf",0) || force->pair_match("thole",0)) special_flag[1] = special_flag[2] = special_flag[3] = 2; // maxwt = max multiplicative factor on atom indices stored in neigh list maxwt = 0; if (special_flag[1] == 2) maxwt = 2; if (special_flag[2] == 2) maxwt = 3; if (special_flag[3] == 2) maxwt = 4; // ------------------------------------------------------------------ // xhold array // free if not needed for this run if (dist_check == 0) { memory->destroy(xhold); maxhold = 0; xhold = NULL; } // first time allocation if (dist_check) { if (maxhold == 0) { maxhold = atom->nmax; memory->create(xhold,maxhold,3,"neigh:xhold"); } } // ------------------------------------------------------------------ // exclusion lists // depend on type, group, molecule settings from neigh_modify // warn if exclusions used with KSpace solver n = atom->ntypes; if (nex_type == 0 && nex_group == 0 && nex_mol == 0) exclude = 0; else exclude = 1; if (nex_type) { if (lmp->kokkos) init_ex_type_kokkos(n); else { memory->destroy(ex_type); memory->create(ex_type,n+1,n+1,"neigh:ex_type"); } for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) ex_type[i][j] = 0; for (i = 0; i < nex_type; i++) { if (ex1_type[i] <= 0 || ex1_type[i] > n || ex2_type[i] <= 0 || ex2_type[i] > n) error->all(FLERR,"Invalid atom type in neighbor exclusion list"); ex_type[ex1_type[i]][ex2_type[i]] = 1; ex_type[ex2_type[i]][ex1_type[i]] = 1; } } if (nex_group) { if (lmp->kokkos) init_ex_bit_kokkos(); else { delete [] ex1_bit; delete [] ex2_bit; ex1_bit = new int[nex_group]; ex2_bit = new int[nex_group]; } for (i = 0; i < nex_group; i++) { ex1_bit[i] = group->bitmask[ex1_group[i]]; ex2_bit[i] = group->bitmask[ex2_group[i]]; } } if (nex_mol) { if (lmp->kokkos) init_ex_mol_bit_kokkos(); else { delete [] ex_mol_bit; ex_mol_bit = new int[nex_mol]; } for (i = 0; i < nex_mol; i++) ex_mol_bit[i] = group->bitmask[ex_mol_group[i]]; } if (exclude && force->kspace && me == 0) error->warning(FLERR,"Neighbor exclusions used with KSpace solver " "may give inconsistent Coulombic energies"); // ------------------------------------------------------------------ // create pairwise lists // one-time call to init_styles() to scan style files and setup // init_pair() creates auxiliary classes: NBin, NStencil, NPair if (firsttime) init_styles(); firsttime = 0; int same = init_pair(); // invoke copy_neighbor_info() in Bin,Stencil,Pair classes // copied once per run in case any cutoff, exclusion, special info changed for (i = 0; i < nbin; i++) neigh_bin[i]->copy_neighbor_info(); for (i = 0; i < nstencil; i++) neigh_stencil[i]->copy_neighbor_info(); for (i = 0; i < nlist; i++) if (neigh_pair[i]) neigh_pair[i]->copy_neighbor_info(); if (!same && comm->me == 0) print_pairwise_info(); // can now delete requests so next run can make new ones // print_pairwise_info() made use of requests // set of NeighLists now stores all needed info for (int i = 0; i < nrequest; i++) { delete requests[i]; requests[i] = NULL; } nrequest = 0; // ------------------------------------------------------------------ // create topology lists // instantiated topo styles can change from run to run init_topology(); } /* ---------------------------------------------------------------------- create and initialize lists of Nbin, Nstencil, NPair classes lists have info on all classes in 3 style*.h files cannot do this in constructor, b/c too early to instantiate classes ------------------------------------------------------------------------- */ void Neighbor::init_styles() { // extract info from NBin classes listed in style_nbin.h nbclass = 0; #define NBIN_CLASS #define NBinStyle(key,Class,bitmasks) nbclass++; #include "style_nbin.h" #undef NBinStyle #undef NBIN_CLASS binclass = new BinCreator[nbclass]; binnames = new char*[nbclass]; binmasks = new int[nbclass]; nbclass = 0; #define NBIN_CLASS #define NBinStyle(key,Class,bitmasks) \ binnames[nbclass] = (char *) #key; \ binclass[nbclass] = &bin_creator; \ binmasks[nbclass++] = bitmasks; #include "style_nbin.h" #undef NBinStyle #undef NBIN_CLASS // extract info from NStencil classes listed in style_nstencil.h nsclass = 0; #define NSTENCIL_CLASS #define NStencilStyle(key,Class,bitmasks) nsclass++; #include "style_nstencil.h" #undef NStencilStyle #undef NSTENCIL_CLASS stencilclass = new StencilCreator[nsclass]; stencilnames = new char*[nsclass]; stencilmasks = new int[nsclass]; nsclass = 0; #define NSTENCIL_CLASS #define NStencilStyle(key,Class,bitmasks) \ stencilnames[nsclass] = (char *) #key; \ stencilclass[nsclass] = &stencil_creator; \ stencilmasks[nsclass++] = bitmasks; #include "style_nstencil.h" #undef NStencilStyle #undef NSTENCIL_CLASS // extract info from NPair classes listed in style_npair.h npclass = 0; #define NPAIR_CLASS #define NPairStyle(key,Class,bitmasks) npclass++; #include "style_npair.h" #undef NPairStyle #undef NPAIR_CLASS pairclass = new PairCreator[npclass]; pairnames = new char*[npclass]; pairmasks = new int[npclass]; npclass = 0; #define NPAIR_CLASS #define NPairStyle(key,Class,bitmasks) \ pairnames[npclass] = (char *) #key; \ pairclass[npclass] = &pair_creator; \ pairmasks[npclass++] = bitmasks; #include "style_npair.h" #undef NPairStyle #undef NPAIR_CLASS } /* ---------------------------------------------------------------------- create and initialize NPair classes ------------------------------------------------------------------------- */ int Neighbor::init_pair() { int i,j,k,m; // test if pairwise lists need to be re-created // no need to re-create if: // neigh style, triclinic, pgsize, oneatom have not changed // current requests = old requests // so just return: // delete requests so next run can make new ones // current set of NeighLists already stores all needed info // requests are compared via identical() before: // any requests are morphed using logic below // any requests are added below, e.g. as parents of pair hybrid skip lists // copy them via requests_new2old() BEFORE any changes made to requests // necessary b/c morphs can change requestor settings (see comment below) int same = 1; if (style != old_style) same = 0; if (triclinic != old_triclinic) same = 0; if (pgsize != old_pgsize) same = 0; if (oneatom != old_oneatom) same = 0; if (nrequest != old_nrequest) same = 0; else for (i = 0; i < nrequest; i++) if (requests[i]->identical(old_requests[i]) == 0) same = 0; #ifdef NEIGH_LIST_DEBUG if (comm->me == 0) printf("SAME flag %d\n",same); #endif if (same) return same; requests_new2old(); // delete old lists since creating new ones for (i = 0; i < nlist; i++) delete lists[i]; for (i = 0; i < nbin; i++) delete neigh_bin[i]; for (i = 0; i < nstencil; i++) delete neigh_stencil[i]; for (i = 0; i < nlist; i++) delete neigh_pair[i]; delete [] lists; delete [] neigh_bin; delete [] neigh_stencil; delete [] neigh_pair; // error check on requests // do not allow occasional, ghost, bin list // b/c it still uses variant of coord2bin() in NPair() method // instead of atom2bin, this could cause error b/c stoms have // moved out of proc domain by time occasional list is built // solution would be to use a different NBin variant // that used Npair::coord2bin(x,ix,iy,iz) (then delete it from NPair) // and stored the ix,iy,iz values for all atoms (including ghosts) // at time of binning when neighbor lists are rebuilt, // similar to what vanilla Nbin::coord2atom() does now in atom2bin if (style == BIN) { for (i = 0; i < nrequest; i++) if (requests[i]->occasional && requests[i]->ghost) error->all(FLERR,"Cannot request an occasional binned neighbor list " "with ghost info"); } // morph requests in various ways // purpose is to avoid duplicate or inefficient builds // may add new requests if a needed request to derive from does not exist // methods: // (1) other = point history and rRESPA lists at their partner lists // (2) skip = create any new non-skip lists needed by pair hybrid skip lists // (3) granular = adjust parent and skip lists for granular onesided usage // (4) h/f = pair up any matching half/full lists // (5) copy = convert as many lists as possible to copy lists // order of morph methods matters: // (1) before (2), b/c (2) needs to know history partner pairings // (2) after (1), b/c (2) may also need to create new history lists // (3) after (2), b/c it adjusts lists created by (2) // (4) after (2) and (3), // b/c (2) may create new full lists, (3) may change them // (5) last, after all lists are finalized, so all possible copies found int nrequest_original = nrequest; morph_other(); morph_skip(); morph_granular(); // this method can change flags set by requestor morph_halffull(); morph_copy(); // create new lists, one per request including added requests // wait to allocate initial pages until copy lists are detected // NOTE: can I allocate now, instead of down below? nlist = nrequest; lists = new NeighList*[nrequest]; neigh_bin = new NBin*[nrequest]; neigh_stencil = new NStencil*[nrequest]; neigh_pair = new NPair*[nrequest]; // allocate new lists // pass list ptr back to requestor (except for Command class) // only for original requests, not ones added by Neighbor class for (i = 0; i < nrequest; i++) { if (requests[i]->kokkos_host || requests[i]->kokkos_device) create_kokkos_list(i); else lists[i] = new NeighList(lmp); lists[i]->index = i; if (requests[i]->pair && i < nrequest_original) { Pair *pair = (Pair *) requests[i]->requestor; pair->init_list(requests[i]->id,lists[i]); } else if (requests[i]->fix && i < nrequest_original) { Fix *fix = (Fix *) requests[i]->requestor; fix->init_list(requests[i]->id,lists[i]); } else if (requests[i]->compute && i < nrequest_original) { Compute *compute = (Compute *) requests[i]->requestor; compute->init_list(requests[i]->id,lists[i]); } } // invoke post_constructor() for all lists // copies info from requests to lists, sets ptrs to related lists for (i = 0; i < nrequest; i++) lists[i]->post_constructor(requests[i]); // assign Bin,Stencil,Pair style to each list int flag; for (i = 0; i < nrequest; i++) { flag = choose_bin(requests[i]); lists[i]->bin_method = flag; if (flag < 0) error->all(FLERR,"Requested neighbor bin option does not exist"); flag = choose_stencil(requests[i]); lists[i]->stencil_method = flag; if (flag < 0) error->all(FLERR,"Requested neighbor stencil method does not exist"); flag = choose_pair(requests[i]); lists[i]->pair_method = flag; if (flag < 0) error->all(FLERR,"Requested neighbor pair method does not exist"); } // instantiate unique Bin,Stencil classes in neigh_bin & neigh_stencil vecs // unique = only one of its style, or request unique flag set (custom cutoff) nbin = 0; for (i = 0; i < nrequest; i++) { requests[i]->index_bin = -1; flag = lists[i]->bin_method; if (flag == 0) continue; for (j = 0; j < nbin; j++) if (neigh_bin[j]->istyle == flag) break; if (j < nbin && !requests[i]->unique) { requests[i]->index_bin = j; continue; } BinCreator bin_creator = binclass[flag-1]; neigh_bin[nbin] = bin_creator(lmp); neigh_bin[nbin]->post_constructor(requests[i]); neigh_bin[nbin]->istyle = flag; requests[i]->index_bin = nbin; nbin++; } nstencil = 0; for (i = 0; i < nrequest; i++) { requests[i]->index_stencil = -1; flag = lists[i]->stencil_method; if (flag == 0) continue; for (j = 0; j < nstencil; j++) if (neigh_stencil[j]->istyle == flag) break; if (j < nstencil && !requests[i]->unique) { requests[i]->index_stencil = j; continue; } StencilCreator stencil_creator = stencilclass[flag-1]; neigh_stencil[nstencil] = stencil_creator(lmp); neigh_stencil[nstencil]->post_constructor(requests[i]); neigh_stencil[nstencil]->istyle = flag; if (lists[i]->bin_method > 0) { neigh_stencil[nstencil]->nb = neigh_bin[requests[i]->index_bin]; if (neigh_stencil[nstencil]->nb == NULL) error->all(FLERR,"Could not assign bin method to neighbor stencil"); } requests[i]->index_stencil = nstencil; nstencil++; } // instantiate one Pair class per list in neigh_pair vec for (i = 0; i < nrequest; i++) { requests[i]->index_pair = -1; flag = lists[i]->pair_method; if (flag == 0) { neigh_pair[i] = NULL; continue; } PairCreator pair_creator = pairclass[flag-1]; neigh_pair[i] = pair_creator(lmp); neigh_pair[i]->post_constructor(requests[i]); neigh_pair[i]->istyle = flag; if (lists[i]->bin_method > 0) { neigh_pair[i]->nb = neigh_bin[requests[i]->index_bin]; if (neigh_pair[i]->nb == NULL) error->all(FLERR,"Could not assign bin method to neighbor pair"); } if (lists[i]->stencil_method > 0) { neigh_pair[i]->ns = neigh_stencil[requests[i]->index_stencil]; if (neigh_pair[i]->ns == NULL) error->all(FLERR,"Could not assign stencil method to neighbor pair"); } requests[i]->index_pair = i; } // allocate initial pages for each list, except if copy flag set // allocate dnum vector of zeroes if set int dnummax = 0; for (i = 0; i < nlist; i++) { if (lists[i]->copy) continue; lists[i]->setup_pages(pgsize,oneatom); dnummax = MAX(dnummax,lists[i]->dnum); } if (dnummax) { delete [] zeroes; zeroes = new double[dnummax]; for (i = 0; i < dnummax; i++) zeroes[i] = 0.0; } // first-time allocation of per-atom data for lists that are built and store // lists that are not built: granhistory, respa inner/middle (no neigh_pair) // lists that do not store: copy // use atom->nmax for both grow() args // i.e. grow first time to expanded size to avoid future reallocs // also Kokkos list initialization int maxatom = atom->nmax; for (i = 0; i < nlist; i++) if (neigh_pair[i] && !lists[i]->copy) lists[i]->grow(maxatom,maxatom); // plist = indices of perpetual NPair classes // perpetual = non-occasional, re-built at every reneighboring // slist = indices of perpetual NStencil classes // perpetual = used by any perpetual NPair class delete [] slist; delete [] plist; nstencil_perpetual = npair_perpetual = 0; slist = new int[nstencil]; plist = new int[nlist]; for (i = 0; i < nlist; i++) { if (lists[i]->occasional == 0 && lists[i]->pair_method) plist[npair_perpetual++] = i; } for (i = 0; i < nstencil; i++) { flag = 0; for (j = 0; j < npair_perpetual; j++) if (lists[plist[j]]->stencil_method == neigh_stencil[i]->istyle) flag = 1; if (flag) slist[nstencil_perpetual++] = i; } // reorder plist vector if necessary // relevant for lists that are derived from a parent list: // half-full,copy,skip // the child index must appear in plist after the parent index // swap two indices within plist when dependency is mis-ordered // start double loop check again whenever a swap is made // done when entire double loop test results in no swaps NeighList *ptr; int done = 0; while (!done) { done = 1; for (i = 0; i < npair_perpetual; i++) { for (k = 0; k < 3; k++) { ptr = NULL; if (k == 0) ptr = lists[plist[i]]->listcopy; if (k == 1) ptr = lists[plist[i]]->listskip; if (k == 2) ptr = lists[plist[i]]->listfull; if (ptr == NULL) continue; for (m = 0; m < nrequest; m++) if (ptr == lists[m]) break; for (j = 0; j < npair_perpetual; j++) if (m == plist[j]) break; if (j < i) continue; int tmp = plist[i]; // swap I,J indices plist[i] = plist[j]; plist[j] = tmp; done = 0; break; } if (!done) break; } } // debug output #ifdef NEIGH_LIST_DEBUG for (i = 0; i < nrequest; i++) lists[i]->print_attributes(); #endif return same; } /* ---------------------------------------------------------------------- scan NeighRequests to set additional flags only for history, respaouter, custom cutoff lists ------------------------------------------------------------------------- */ void Neighbor::morph_other() { NeighRequest *irq; for (int i = 0; i < nrequest; i++) { irq = requests[i]; // if history, point this list and partner list at each other if (irq->history) { irq->historylist = i-1; requests[i-1]->history_partner = 1; requests[i-1]->historylist = i; } // if respaouter, point all associated rRESPA lists at each other if (irq->respaouter) { if (requests[i-1]->respainner) { irq->respainnerlist = i-1; requests[i-1]->respaouterlist = i; } else { irq->respamiddlelist = i-1; requests[i-1]->respaouterlist = i; requests[i-1]->respainnerlist = i-1; irq->respainnerlist = i-2; requests[i-2]->respaouterlist = i; requests[i-2]->respamiddlelist = i-1; } } // if cut flag set by requestor, set unique flag // this forces Pair,Stencil,Bin styles to be instantiated separately if (irq->cut) irq->unique = 1; } } /* ---------------------------------------------------------------------- scan NeighRequests to process all skip lists look for a matching non-skip list if one exists, point at it via skiplist else make new parent via copy_request() and point at it ------------------------------------------------------------------------- */ void Neighbor::morph_skip() { int i,j,inewton,jnewton; NeighRequest *irq,*jrq,*nrq; for (i = 0; i < nrequest; i++) { irq = requests[i]; // only processing skip lists if (!irq->skip) continue; // these lists are created other ways, no need for skipping // halffull list and its full parent may both skip, // but are checked to insure matching skip info if (irq->history) continue; if (irq->respainner || irq->respamiddle) continue; if (irq->halffull) continue; if (irq->copy) continue; // check all other lists for (j = 0; j < nrequest; j++) { if (i == j) continue; jrq = requests[j]; // can only skip from a perpetual non-skip list if (jrq->occasional) continue; if (jrq->skip) continue; // both lists must be half, or both full if (irq->half != jrq->half) continue; if (irq->full != jrq->full) continue; // both lists must be newton on, or both newton off // IJ newton = 1 for newton on, 2 for newton off inewton = irq->newton; if (inewton == 0) inewton = force->newton_pair ? 1 : 2; jnewton = jrq->newton; if (jnewton == 0) jnewton = force->newton_pair ? 1 : 2; if (inewton != jnewton) continue; // these flags must be same, // else 2 lists do not store same pairs // or their data structures are different // this includes custom cutoff set by requestor // no need to check respaouter b/c it stores same pairs // no need to check dnum b/c only set for history // NOTE: need check for 2 Kokkos flags? if (irq->ghost != jrq->ghost) continue; if (irq->size != jrq->size) continue; if (irq->bond != jrq->bond) continue; if (irq->omp != jrq->omp) continue; if (irq->intel != jrq->intel) continue; if (irq->kokkos_host != jrq->kokkos_host) continue; if (irq->kokkos_device != jrq->kokkos_device) continue; if (irq->ssa != jrq->ssa) continue; if (irq->cut != jrq->cut) continue; if (irq->cutoff != jrq->cutoff) continue; // 2 lists are a match break; } // if matching list exists, point to it // else create a new identical list except non-skip // for new list, set neigh = 1, skip = 0, no skip vec/array, // copy unique flag (since copy_request() will not do it) // note: parents of skip lists do not have associated history list // b/c child skip lists store their own history info if (j < nrequest) irq->skiplist = j; else { int newrequest = request(this,-1); irq->skiplist = newrequest; nrq = requests[newrequest]; nrq->copy_request(irq,0); nrq->pair = nrq->fix = nrq->compute = nrq->command = 0; nrq->neigh = 1; nrq->skip = 0; if (irq->unique) nrq->unique = 1; } } } /* ---------------------------------------------------------------------- scan NeighRequests just added by morph_skip for hybrid granular adjust newton/oneside parent settings if children require onesided skipping also set children off2on flag if parent becomes a newton off list this is needed because line/gran and tri/gran pair styles require onesided neigh lists and system newton on, but parent list must be newton off to enable the onesided skipping ------------------------------------------------------------------------- */ void Neighbor::morph_granular() { int i,j; NeighRequest *irq,*jrq; for (i = 0; i < nrequest; i++) { irq = requests[i]; // only examine NeighRequests added by morph_skip() // only those with size attribute for granular systems if (!irq->neigh) continue; if (!irq->size) continue; // check children of this list int onesided = -1; for (j = 0; j < nrequest; j++) { jrq = requests[j]; // only consider JRQ pair, size lists that skip from Irq list if (!jrq->pair) continue; if (!jrq->size) continue; if (!jrq->skip || jrq->skiplist != i) continue; // onesided = -1 if no children // onesided = 0/1 = child granonesided value if same for all children // onesided = 2 if children have different granonesided values if (onesided < 0) onesided = jrq->granonesided; else if (onesided != jrq->granonesided) onesided = 2; if (onesided == 2) break; } // if onesided = 2, parent has children with both granonesided = 0/1 // force parent newton off (newton = 2) to enable onesided skip by child // set parent granonesided = 0, so it stores all neighs in usual manner // set off2on = 1 for all children, since they expect newton on lists // this is b/c granonesided only set by line/gran and tri/gran which // both require system newton on if (onesided == 2) { irq->newton = 2; irq->granonesided = 0; for (j = 0; j < nrequest; j++) { jrq = requests[j]; // only consider JRQ pair, size lists that skip from Irq list if (!jrq->pair) continue; if (!jrq->size) continue; if (!jrq->skip || jrq->skiplist != i) continue; jrq->off2on = 1; } } } } /* ---------------------------------------------------------------------- scan NeighRequests for possible half lists to derive from full lists if 2 requests match, set half list to derive from full list ------------------------------------------------------------------------- */ void Neighbor::morph_halffull() { int i,j; NeighRequest *irq,*jrq; for (i = 0; i < nrequest; i++) { irq = requests[i]; // only processing half lists if (!irq->half) continue; // Kokkos doesn't yet support half from full if (irq->kokkos_host) continue; if (irq->kokkos_device) continue; // these lists are created other ways, no need for halffull // do want to process skip lists if (irq->history) continue; if (irq->respainner || irq->respamiddle) continue; if (irq->copy) continue; // check all other lists for (j = 0; j < nrequest; j++) { if (i == j) continue; jrq = requests[j]; // can only derive from a perpetual full list // newton setting of derived list does not matter if (jrq->occasional) continue; if (!jrq->full) continue; // these flags must be same, // else 2 lists do not store same pairs // or their data structures are different // this includes custom cutoff set by requestor // no need to check respaouter b/c it stores same pairs // no need to check dnum b/c only set for history if (irq->ghost != jrq->ghost) continue; if (irq->size != jrq->size) continue; if (irq->bond != jrq->bond) continue; if (irq->omp != jrq->omp) continue; if (irq->intel != jrq->intel) continue; if (irq->kokkos_host != jrq->kokkos_host) continue; if (irq->kokkos_device != jrq->kokkos_device) continue; if (irq->ssa != jrq->ssa) continue; if (irq->cut != jrq->cut) continue; if (irq->cutoff != jrq->cutoff) continue; // skip flag must be same // if both are skip lists, skip info must match if (irq->skip != jrq->skip) continue; if (irq->skip && irq->same_skip(jrq) == 0) continue; // 2 lists are a match break; } // if matching list exists, point to it if (j < nrequest) { irq->halffull = 1; irq->halffulllist = j; } } } /* ---------------------------------------------------------------------- scan NeighRequests for possible copies if 2 requests match, turn one into a copy of the other ------------------------------------------------------------------------- */ void Neighbor::morph_copy() { int i,j,inewton,jnewton; NeighRequest *irq,*jrq; for (i = 0; i < nrequest; i++) { irq = requests[i]; // this list is already a copy list due to another morph method if (irq->copy) continue; // these lists are created other ways, no need to copy // skip lists are eligible to become a copy list if (irq->history) continue; if (irq->respainner || irq->respamiddle) continue; // check all other lists for (j = 0; j < nrequest; j++) { if (i == j) continue; jrq = requests[j]; // other list is already copied from this one if (jrq->copy && jrq->copylist == i) continue; // other list (jrq) to copy from must be perpetual // list that becomes a copy list (irq) can be perpetual or occasional // if both lists are perpetual, require j < i // to prevent circular dependence with 3 or more copies of a list if (jrq->occasional) continue; if (!irq->occasional && j > i) continue; // both lists must be half, or both full if (irq->half != jrq->half) continue; if (irq->full != jrq->full) continue; // both lists must be newton on, or both newton off // IJ newton = 1 for newton on, 2 for newton off inewton = irq->newton; if (inewton == 0) inewton = force->newton_pair ? 1 : 2; jnewton = jrq->newton; if (jnewton == 0) jnewton = force->newton_pair ? 1 : 2; if (inewton != jnewton) continue; // ok for non-ghost list to copy from ghost list, but not vice versa if (irq->ghost && !jrq->ghost) continue; + // do not copy from a history list or a respa middle/inner list + + if (jrq->history) continue; + if (jrq->respamiddle) continue; + if (jrq->respainner) continue; + // these flags must be same, // else 2 lists do not store same pairs // or their data structures are different // this includes custom cutoff set by requestor // no need to check respaouter b/c it stores same pairs // no need to check omp b/c it stores same pairs // no need to check dnum b/c only set for history // NOTE: need check for 2 Kokkos flags? if (irq->size != jrq->size) continue; if (irq->bond != jrq->bond) continue; if (irq->intel != jrq->intel) continue; if (irq->kokkos_host != jrq->kokkos_host) continue; if (irq->kokkos_device != jrq->kokkos_device) continue; if (irq->ssa != jrq->ssa) continue; if (irq->cut != jrq->cut) continue; if (irq->cutoff != jrq->cutoff) continue; // skip flag must be same // if both are skip lists, skip info must match if (irq->skip != jrq->skip) continue; if (irq->skip && irq->same_skip(jrq) == 0) continue; // 2 lists are a match break; } // turn list I into a copy of list J // do not copy a list from another copy list, but from its parent list if (j < nrequest) { irq->copy = 1; if (jrq->copy) irq->copylist = jrq->copylist; else irq->copylist = j; } } } /* ---------------------------------------------------------------------- create and initialize NTopo classes ------------------------------------------------------------------------- */ void Neighbor::init_topology() { int i,m; if (!atom->molecular) return; // set flags that determine which topology neighbor classes to use // these settings could change from run to run, depending on fixes defined // bonds,etc can only be broken for atom->molecular = 1, not 2 // SHAKE sets bonds and angles negative // gcmc sets all bonds, angles, etc negative // bond_quartic sets bonds to 0 // delete_bonds sets all interactions negative int bond_off = 0; int angle_off = 0; for (i = 0; i < modify->nfix; i++) if ((strcmp(modify->fix[i]->style,"shake") == 0) || (strcmp(modify->fix[i]->style,"rattle") == 0)) bond_off = angle_off = 1; if (force->bond && force->bond_match("quartic")) bond_off = 1; if (atom->avec->bonds_allow && atom->molecular == 1) { for (i = 0; i < atom->nlocal; i++) { if (bond_off) break; for (m = 0; m < atom->num_bond[i]; m++) if (atom->bond_type[i][m] <= 0) bond_off = 1; } } if (atom->avec->angles_allow && atom->molecular == 1) { for (i = 0; i < atom->nlocal; i++) { if (angle_off) break; for (m = 0; m < atom->num_angle[i]; m++) if (atom->angle_type[i][m] <= 0) angle_off = 1; } } int dihedral_off = 0; if (atom->avec->dihedrals_allow && atom->molecular == 1) { for (i = 0; i < atom->nlocal; i++) { if (dihedral_off) break; for (m = 0; m < atom->num_dihedral[i]; m++) if (atom->dihedral_type[i][m] <= 0) dihedral_off = 1; } } int improper_off = 0; if (atom->avec->impropers_allow && atom->molecular == 1) { for (i = 0; i < atom->nlocal; i++) { if (improper_off) break; for (m = 0; m < atom->num_improper[i]; m++) if (atom->improper_type[i][m] <= 0) improper_off = 1; } } for (i = 0; i < modify->nfix; i++) if ((strcmp(modify->fix[i]->style,"gcmc") == 0)) bond_off = angle_off = dihedral_off = improper_off = 1; // sync on/off settings across all procs int onoff = bond_off; MPI_Allreduce(&onoff,&bond_off,1,MPI_INT,MPI_MAX,world); onoff = angle_off; MPI_Allreduce(&onoff,&angle_off,1,MPI_INT,MPI_MAX,world); onoff = dihedral_off; MPI_Allreduce(&onoff,&dihedral_off,1,MPI_INT,MPI_MAX,world); onoff = improper_off; MPI_Allreduce(&onoff,&improper_off,1,MPI_INT,MPI_MAX,world); // instantiate NTopo classes if (atom->avec->bonds_allow) { int old_bondwhich = bondwhich; if (atom->molecular == 2) bondwhich = TEMPLATE; else if (bond_off) bondwhich = PARTIAL; else bondwhich = ALL; if (!neigh_bond || bondwhich != old_bondwhich) { delete neigh_bond; if (bondwhich == ALL) neigh_bond = new NTopoBondAll(lmp); else if (bondwhich == PARTIAL) neigh_bond = new NTopoBondPartial(lmp); else if (bondwhich == TEMPLATE) neigh_bond = new NTopoBondTemplate(lmp); } } if (atom->avec->angles_allow) { int old_anglewhich = anglewhich; if (atom->molecular == 2) anglewhich = TEMPLATE; else if (angle_off) anglewhich = PARTIAL; else anglewhich = ALL; if (!neigh_angle || anglewhich != old_anglewhich) { delete neigh_angle; if (anglewhich == ALL) neigh_angle = new NTopoAngleAll(lmp); else if (anglewhich == PARTIAL) neigh_angle = new NTopoAnglePartial(lmp); else if (anglewhich == TEMPLATE) neigh_angle = new NTopoAngleTemplate(lmp); } } if (atom->avec->dihedrals_allow) { int old_dihedralwhich = dihedralwhich; if (atom->molecular == 2) dihedralwhich = TEMPLATE; else if (dihedral_off) dihedralwhich = PARTIAL; else dihedralwhich = ALL; if (!neigh_dihedral || dihedralwhich != old_dihedralwhich) { delete neigh_dihedral; if (dihedralwhich == ALL) neigh_dihedral = new NTopoDihedralAll(lmp); else if (dihedralwhich == PARTIAL) neigh_dihedral = new NTopoDihedralPartial(lmp); else if (dihedralwhich == TEMPLATE) neigh_dihedral = new NTopoDihedralTemplate(lmp); } } if (atom->avec->impropers_allow) { int old_improperwhich = improperwhich; if (atom->molecular == 2) improperwhich = TEMPLATE; else if (improper_off) improperwhich = PARTIAL; else improperwhich = ALL; if (!neigh_improper || improperwhich != old_improperwhich) { delete neigh_improper; if (improperwhich == ALL) neigh_improper = new NTopoImproperAll(lmp); else if (improperwhich == PARTIAL) neigh_improper = new NTopoImproperPartial(lmp); else if (improperwhich == TEMPLATE) neigh_improper = new NTopoImproperTemplate(lmp); } } } /* ---------------------------------------------------------------------- output summary of pairwise neighbor list info only called by proc 0 ------------------------------------------------------------------------- */ void Neighbor::print_pairwise_info() { int i,m; char str[128]; NeighRequest *rq; FILE *out; const double cutghost = MAX(cutneighmax,comm->cutghostuser); double binsize, bbox[3]; bbox[0] = bboxhi[0]-bboxlo[0]; bbox[1] = bboxhi[1]-bboxlo[1]; bbox[2] = bboxhi[2]-bboxlo[2]; if (binsizeflag) binsize = binsize_user; else if (style == BIN) binsize = 0.5*cutneighmax; else binsize = 0.5*cutneighmin; if (binsize == 0.0) binsize = bbox[0]; int nperpetual = 0; int noccasional = 0; int nextra = 0; for (i = 0; i < nlist; i++) { if (lists[i]->pair_method == 0) nextra++; else if (lists[i]->occasional) noccasional++; else nperpetual++; } for (m = 0; m < 2; m++) { if (m == 0) out = screen; else out = logfile; if (out) { fprintf(out,"Neighbor list info ...\n"); fprintf(out," update every %d steps, delay %d steps, check %s\n", every,delay,dist_check ? "yes" : "no"); fprintf(out," max neighbors/atom: %d, page size: %d\n", oneatom, pgsize); fprintf(out," master list distance cutoff = %g\n",cutneighmax); fprintf(out," ghost atom cutoff = %g\n",cutghost); if (style != NSQ) fprintf(out," binsize = %g, bins = %g %g %g\n",binsize, ceil(bbox[0]/binsize), ceil(bbox[1]/binsize), ceil(bbox[2]/binsize)); fprintf(out," %d neighbor lists, " "perpetual/occasional/extra = %d %d %d\n", nlist,nperpetual,noccasional,nextra); for (i = 0; i < nlist; i++) { rq = requests[i]; if (rq->pair) { char *pname = force->pair_match_ptr((Pair *) rq->requestor); sprintf(str," (%d) pair %s",i+1,pname); } else if (rq->fix) { sprintf(str," (%d) fix %s",i+1,((Fix *) rq->requestor)->style); } else if (rq->compute) { sprintf(str," (%d) compute %s",i+1, ((Compute *) rq->requestor)->style); } else if (rq->command) { sprintf(str," (%d) command %s",i+1,rq->command_style); } else if (rq->neigh) { sprintf(str," (%d) neighbor class addition",i+1); } fprintf(out,"%s",str); if (rq->occasional) fprintf(out,", occasional"); else fprintf(out,", perpetual"); // order these to get single output of most relevant if (rq->history) fprintf(out,", history for (%d)",rq->historylist+1); else if (rq->copy) fprintf(out,", copy from (%d)",rq->copylist+1); else if (rq->halffull) fprintf(out,", half/full from (%d)",rq->halffulllist+1); else if (rq->skip) fprintf(out,", skip from (%d)",rq->skiplist+1); fprintf(out,"\n"); // list of neigh list attributes fprintf(out," attributes: "); if (rq->half) fprintf(out,"half"); else if (rq->full) fprintf(out,"full"); if (rq->newton == 0) { if (force->newton_pair) fprintf(out,", newton on"); else fprintf(out,", newton off"); } else if (rq->newton == 1) fprintf(out,", newton on"); else if (rq->newton == 2) fprintf(out,", newton off"); if (rq->ghost) fprintf(out,", ghost"); if (rq->size) fprintf(out,", size"); if (rq->history) fprintf(out,", history"); if (rq->granonesided) fprintf(out,", onesided"); if (rq->respainner) fprintf(out,", respa outer"); if (rq->respamiddle) fprintf(out,", respa middle"); if (rq->respaouter) fprintf(out,", respa inner"); if (rq->bond) fprintf(out,", bond"); if (rq->omp) fprintf(out,", omp"); if (rq->intel) fprintf(out,", intel"); if (rq->kokkos_device) fprintf(out,", kokkos_device"); if (rq->kokkos_host) fprintf(out,", kokkos_host"); if (rq->ssa) fprintf(out,", ssa"); if (rq->cut) fprintf(out,", cut %g",rq->cutoff); if (rq->off2on) fprintf(out,", off2on"); fprintf(out,"\n"); fprintf(out," "); if (lists[i]->pair_method == 0) fprintf(out,"pair build: none\n"); else fprintf(out,"pair build: %s\n",pairnames[lists[i]->pair_method-1]); fprintf(out," "); if (lists[i]->stencil_method == 0) fprintf(out,"stencil: none\n"); else fprintf(out,"stencil: %s\n", stencilnames[lists[i]->stencil_method-1]); fprintf(out," "); if (lists[i]->bin_method == 0) fprintf(out,"bin: none\n"); else fprintf(out,"bin: %s\n",binnames[lists[i]->bin_method-1]); } /* fprintf(out," %d stencil methods\n",nstencil); for (i = 0; i < nstencil; i++) fprintf(out," (%d) %s\n", i+1,stencilnames[neigh_stencil[i]->istyle-1]); fprintf(out," %d bin methods\n",nbin); for (i = 0; i < nbin; i++) fprintf(out," (%d) %s\n",i+1,binnames[neigh_bin[i]->istyle-1]); */ } } } /* ---------------------------------------------------------------------- make copy of current requests and Neighbor params used to compare to when next run occurs ------------------------------------------------------------------------- */ void Neighbor::requests_new2old() { for (int i = 0; i < old_nrequest; i++) delete old_requests[i]; memory->sfree(old_requests); old_nrequest = nrequest; old_requests = (NeighRequest **) memory->smalloc(old_nrequest*sizeof(NeighRequest *), "neighbor:old_requests"); for (int i = 0; i < old_nrequest; i++) { old_requests[i] = new NeighRequest(lmp); old_requests[i]->copy_request(requests[i],1); } old_style = style; old_triclinic = triclinic; old_pgsize = pgsize; old_oneatom = oneatom; } +/* ---------------------------------------------------------------------- + find and return request made by classptr + if not found or classpt = NULL, return NULL +------------------------------------------------------------------------- */ + +NeighRequest *Neighbor::find_request(void *classptr) +{ + if (classptr == NULL) return NULL; + + for (int i = 0; i < nrequest; i++) + if (requests[i]->requestor == classptr) return requests[i]; + + return NULL; +} + /* ---------------------------------------------------------------------- assign NBin class to a NeighList use neigh request settings to build mask match mask to list of masks of known Nbin classes return index+1 of match in list of masks return 0 for no binning return -1 if no match ------------------------------------------------------------------------- */ int Neighbor::choose_bin(NeighRequest *rq) { // no binning needed if (style == NSQ) return 0; if (rq->skip || rq->copy || rq->halffull) return 0; if (rq->history) return 0; if (rq->respainner || rq->respamiddle) return 0; // use request settings to match exactly one NBin class mask // checks are bitwise using NeighConst bit masks int mask; for (int i = 0; i < nbclass; i++) { mask = binmasks[i]; // require match of these request flags and mask bits // (!A != !B) is effectively a logical xor if (!rq->intel != !(mask & NB_INTEL)) continue; if (!rq->ssa != !(mask & NB_SSA)) continue; if (!rq->kokkos_device != !(mask & NB_KOKKOS_DEVICE)) continue; if (!rq->kokkos_host != !(mask & NB_KOKKOS_HOST)) continue; return i+1; } // error return if matched none return -1; } /* ---------------------------------------------------------------------- assign NStencil class to a NeighList use neigh request settings to build mask match mask to list of masks of known NStencil classes return index+1 of match in list of masks return 0 for no binning return -1 if no match ------------------------------------------------------------------------- */ int Neighbor::choose_stencil(NeighRequest *rq) { // no stencil creation needed if (style == NSQ) return 0; if (rq->skip || rq->copy || rq->halffull) return 0; if (rq->history) return 0; if (rq->respainner || rq->respamiddle) return 0; // convert newton request to newtflag = on or off int newtflag; if (rq->newton == 0 && newton_pair) newtflag = 1; else if (rq->newton == 0 && !newton_pair) newtflag = 0; else if (rq->newton == 1) newtflag = 1; else if (rq->newton == 2) newtflag = 0; //printf("STENCIL RQ FLAGS: hff %d %d n %d g %d s %d newtflag %d\n", // rq->half,rq->full,rq->newton,rq->ghost,rq->ssa, // newtflag); // use request and system settings to match exactly one NStencil class mask // checks are bitwise using NeighConst bit masks int mask; for (int i = 0; i < nsclass; i++) { mask = stencilmasks[i]; //printf("III %d: half %d full %d newton %d newtoff %d ghost %d ssa %d\n", // i,mask & NS_HALF,mask & NS_FULL,mask & NS_NEWTON, // mask & NS_NEWTOFF,mask & NS_GHOST,mask & NS_SSA); // exactly one of half or full is set and must match if (rq->half) { if (!(mask & NS_HALF)) continue; } else if (rq->full) { if (!(mask & NS_FULL)) continue; } // newtflag is on or off and must match if (newtflag) { if (!(mask & NS_NEWTON)) continue; } else if (!newtflag) { if (!(mask & NS_NEWTOFF)) continue; } // require match of these request flags and mask bits // (!A != !B) is effectively a logical xor if (!rq->ghost != !(mask & NS_GHOST)) continue; if (!rq->ssa != !(mask & NS_SSA)) continue; // neighbor style is BIN or MULTI and must match if (style == BIN) { if (!(mask & NS_BIN)) continue; } else if (style == MULTI) { if (!(mask & NS_MULTI)) continue; } // dimension is 2 or 3 and must match if (dimension == 2) { if (!(mask & NS_2D)) continue; } else if (dimension == 3) { if (!(mask & NS_3D)) continue; } // domain triclinic flag is on or off and must match if (triclinic) { if (!(mask & NS_TRI)) continue; } else if (!triclinic) { if (!(mask & NS_ORTHO)) continue; } return i+1; } // error return if matched none return -1; } /* ---------------------------------------------------------------------- assign NPair class to a NeighList use neigh request settings to build mask match mask to list of masks of known NPair classes return index+1 of match in list of masks return 0 for no binning return -1 if no match ------------------------------------------------------------------------- */ int Neighbor::choose_pair(NeighRequest *rq) { // no neighbor list build performed if (rq->history) return 0; if (rq->respainner || rq->respamiddle) return 0; // error check for includegroup with ghost neighbor request if (includegroup && rq->ghost) error->all(FLERR,"Neighbor include group not allowed with ghost neighbors"); // convert newton request to newtflag = on or off int newtflag; if (rq->newton == 0 && newton_pair) newtflag = 1; else if (rq->newton == 0 && !newton_pair) newtflag = 0; else if (rq->newton == 1) newtflag = 1; else if (rq->newton == 2) newtflag = 0; int molecular = atom->molecular; //printf("PAIR RQ FLAGS: hf %d %d n %d g %d sz %d gos %d r %d b %d o %d i %d " // "kk %d %d ss %d dn %d sk %d cp %d hf %d oo %d\n", // rq->half,rq->full,rq->newton,rq->ghost,rq->size, // rq->granonesided,rq->respaouter,rq->bond,rq->omp,rq->intel, // rq->kokkos_host,rq->kokkos_device,rq->ssa,rq->dnum, // rq->skip,rq->copy,rq->halffull,rq->off2on); // use request and system settings to match exactly one NPair class mask // checks are bitwise using NeighConst bit masks int mask; for (int i = 0; i < npclass; i++) { mask = pairmasks[i]; //printf(" PAIR NAMES i %d %d name %s mask %d\n",i,nrequest, // pairnames[i],pairmasks[i]); // if copy request, no further checks needed, just return or continue // Kokkos device/host flags must also match in order to copy if (rq->copy) { if (!(mask & NP_COPY)) continue; if (!rq->kokkos_device != !(mask & NP_KOKKOS_DEVICE)) continue; if (!rq->kokkos_host != !(mask & NP_KOKKOS_HOST)) continue; return i+1; } // exactly one of half or full is set and must match if (rq->half) { if (!(mask & NP_HALF)) continue; } else if (rq->full) { if (!(mask & NP_FULL)) continue; } // newtflag is on or off and must match if (newtflag) { if (!(mask & NP_NEWTON)) continue; } else if (!newtflag) { if (!(mask & NP_NEWTOFF)) continue; } // if molecular on, do not match ATOMONLY (b/c a MOLONLY Npair exists) // if molecular off, do not match MOLONLY (b/c an ATOMONLY Npair exists) if (molecular) { if (mask & NP_ATOMONLY) continue; } else if (!molecular) { if (mask & NP_MOLONLY) continue; } // require match of these request flags and mask bits // (!A != !B) is effectively a logical xor if (!rq->ghost != !(mask & NP_GHOST)) continue; if (!rq->size != !(mask & NP_SIZE)) continue; if (!rq->respaouter != !(mask & NP_RESPA)) continue; if (!rq->granonesided != !(mask & NP_ONESIDE)) continue; if (!rq->respaouter != !(mask & NP_RESPA)) continue; if (!rq->bond != !(mask & NP_BOND)) continue; if (!rq->omp != !(mask & NP_OMP)) continue; if (!rq->intel != !(mask & NP_INTEL)) continue; if (!rq->kokkos_device != !(mask & NP_KOKKOS_DEVICE)) continue; if (!rq->kokkos_host != !(mask & NP_KOKKOS_HOST)) continue; if (!rq->ssa != !(mask & NP_SSA)) continue; if (!rq->skip != !(mask & NP_SKIP)) continue; if (!rq->halffull != !(mask & NP_HALF_FULL)) continue; if (!rq->off2on != !(mask & NP_OFF2ON)) continue; // neighbor style is one of NSQ,BIN,MULTI and must match if (style == NSQ) { if (!(mask & NP_NSQ)) continue; } else if (style == BIN) { if (!(mask & NP_BIN)) continue; } else if (style == MULTI) { if (!(mask & NP_MULTI)) continue; } // domain triclinic flag is on or off and must match if (triclinic) { if (!(mask & NP_TRI)) continue; } else if (!triclinic) { if (!(mask & NP_ORTHO)) continue; } return i+1; } // error return if matched none return -1; } /* ---------------------------------------------------------------------- called by other classes to request a pairwise neighbor list ------------------------------------------------------------------------- */ int Neighbor::request(void *requestor, int instance) { if (nrequest == maxrequest) { maxrequest += RQDELTA; requests = (NeighRequest **) memory->srealloc(requests,maxrequest*sizeof(NeighRequest *), "neighbor:requests"); } requests[nrequest] = new NeighRequest(lmp); requests[nrequest]->index = nrequest; requests[nrequest]->requestor = requestor; requests[nrequest]->requestor_instance = instance; nrequest++; return nrequest-1; } /* ---------------------------------------------------------------------- one instance per entry in style_neigh_bin.h ------------------------------------------------------------------------- */ template NBin *Neighbor::bin_creator(LAMMPS *lmp) { return new T(lmp); } /* ---------------------------------------------------------------------- one instance per entry in style_neigh_stencil.h ------------------------------------------------------------------------- */ template NStencil *Neighbor::stencil_creator(LAMMPS *lmp) { return new T(lmp); } /* ---------------------------------------------------------------------- one instance per entry in style_neigh_pair.h ------------------------------------------------------------------------- */ template NPair *Neighbor::pair_creator(LAMMPS *lmp) { return new T(lmp); } /* ---------------------------------------------------------------------- setup neighbor binning and neighbor stencils called before run and every reneighbor if box size/shape changes only operates on perpetual lists build_one() operates on occasional lists ------------------------------------------------------------------------- */ void Neighbor::setup_bins() { // invoke setup_bins() for all NBin // actual binning is performed in build() for (int i = 0; i < nbin; i++) neigh_bin[i]->setup_bins(style); // invoke create_setup() and create() for all perpetual NStencil // same ops performed for occasional lists in build_one() for (int i = 0; i < nstencil_perpetual; i++) { neigh_stencil[slist[i]]->create_setup(); neigh_stencil[slist[i]]->create(); } last_setup_bins = update->ntimestep; } /* ---------------------------------------------------------------------- */ int Neighbor::decide() { if (must_check) { bigint n = update->ntimestep; if (restart_check && n == output->next_restart) return 1; for (int i = 0; i < fix_check; i++) if (n == modify->fix[fixchecklist[i]]->next_reneighbor) return 1; } ago++; if (ago >= delay && ago % every == 0) { if (build_once) return 0; if (dist_check == 0) return 1; return check_distance(); } else return 0; } /* ---------------------------------------------------------------------- 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 Neighbor::check_distance() { double delx,dely,delz,rsq; double delta,deltasq,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; double **x = atom->x; int nlocal = atom->nlocal; if (includegroup) nlocal = atom->nfirst; int flag = 0; for (int i = 0; i < nlocal; i++) { delx = x[i][0] - xhold[i][0]; dely = x[i][1] - xhold[i][1]; delz = x[i][2] - xhold[i][2]; rsq = delx*delx + dely*dely + delz*delz; if (rsq > deltasq) flag = 1; } int flagall; MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_MAX,world); if (flagall && ago == MAX(every,delay)) ndanger++; return flagall; } /* ---------------------------------------------------------------------- build perpetual neighbor lists called at setup and every few timesteps during run or minimization topology lists also built if topoflag = 1 (Kokkos calls with topoflag=0) ------------------------------------------------------------------------- */ void Neighbor::build(int topoflag) { int i,m; ago = 0; ncalls++; lastcall = update->ntimestep; int nlocal = atom->nlocal; int nall = nlocal + atom->nghost; // check that using special bond flags will not overflow neigh lists if (nall > NEIGHMASK) error->one(FLERR,"Too many local+ghost atoms for neighbor list"); // store current atom positions and box size if needed if (dist_check) { double **x = atom->x; if (includegroup) nlocal = atom->nfirst; if (atom->nmax > maxhold) { maxhold = atom->nmax; memory->destroy(xhold); memory->create(xhold,maxhold,3,"neigh:xhold"); } for (i = 0; i < nlocal; i++) { xhold[i][0] = x[i][0]; xhold[i][1] = x[i][1]; xhold[i][2] = x[i][2]; } 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]; } } } } // bin atoms for all NBin instances // not just NBin associated with perpetual lists, also occasional lists // b/c cannot wait to bin occasional lists in build_one() call // if bin then, atoms may have moved outside of proc domain & bin extent, // leading to errors or even a crash if (style != NSQ) { for (int i = 0; i < nbin; i++) { neigh_bin[i]->bin_atoms_setup(nall); neigh_bin[i]->bin_atoms(); } } // build pairwise lists for all perpetual NPair/NeighList // grow() with nlocal/nall args so that only realloc if have to for (i = 0; i < npair_perpetual; i++) { m = plist[i]; if (!lists[m]->copy) lists[m]->grow(nlocal,nall); neigh_pair[m]->build_setup(); neigh_pair[m]->build(lists[m]); } // build topology lists for bonds/angles/etc if (atom->molecular && topoflag) build_topology(); } /* ---------------------------------------------------------------------- build topology neighbor lists: bond, angle, dihedral, improper copy their list info back to Neighbor for access by bond/angle/etc classes ------------------------------------------------------------------------- */ void Neighbor::build_topology() { if (force->bond) { neigh_bond->build(); nbondlist = neigh_bond->nbondlist; bondlist = neigh_bond->bondlist; } if (force->angle) { neigh_angle->build(); nanglelist = neigh_angle->nanglelist; anglelist = neigh_angle->anglelist; } if (force->dihedral) { neigh_dihedral->build(); ndihedrallist = neigh_dihedral->ndihedrallist; dihedrallist = neigh_dihedral->dihedrallist; } if (force->improper) { neigh_improper->build(); nimproperlist = neigh_improper->nimproperlist; improperlist = neigh_improper->improperlist; } } /* ---------------------------------------------------------------------- build a single occasional pairwise neighbor list indexed by I called by other classes ------------------------------------------------------------------------- */ void Neighbor::build_one(class NeighList *mylist, int preflag) { // check if list structure is initialized if (mylist == NULL) error->all(FLERR,"Trying to build an occasional neighbor list " "before initialization completed"); // build_one() should never be invoked on a perpetual list if (!mylist->occasional) error->all(FLERR,"Neighbor build one invoked on perpetual list"); // no need to build if already built since last re-neighbor // preflag is set by fix bond/create and fix bond/swap // b/c they invoke build_one() on same step neigh list is re-built, // but before re-build, so need to use ">" instead of ">=" NPair *np = neigh_pair[mylist->index]; if (preflag) { if (np->last_build > lastcall) return; } else { if (np->last_build >= lastcall) return; } // if this is copy list and parent is occasional list, // or this is halffull and parent is occasional list, // insure parent is current if (mylist->listcopy && mylist->listcopy->occasional) build_one(mylist->listcopy,preflag); if (mylist->listfull && mylist->listfull->occasional) build_one(mylist->listfull,preflag); // create stencil if hasn't been created since last setup_bins() call NStencil *ns = np->ns; if (ns && ns->last_stencil < last_setup_bins) { ns->create_setup(); ns->create(); } // build the list if (!mylist->copy) mylist->grow(atom->nlocal,atom->nlocal+atom->nghost); np->build_setup(); np->build(mylist); } /* ---------------------------------------------------------------------- set neighbor style and skin distance ------------------------------------------------------------------------- */ void Neighbor::set(int narg, char **arg) { if (narg != 2) error->all(FLERR,"Illegal neighbor command"); skin = force->numeric(FLERR,arg[0]); if (skin < 0.0) error->all(FLERR,"Illegal neighbor command"); if (strcmp(arg[1],"nsq") == 0) style = NSQ; else if (strcmp(arg[1],"bin") == 0) style = BIN; else if (strcmp(arg[1],"multi") == 0) style = MULTI; else error->all(FLERR,"Illegal neighbor command"); if (style == MULTI && lmp->citeme) lmp->citeme->add(cite_neigh_multi); } /* ---------------------------------------------------------------------- reset timestamps in all NeignBin, NStencil, NPair classes so that neighbor lists will rebuild properly with timestep change ditto for lastcall and last_setup_bins ------------------------------------------------------------------------- */ void Neighbor::reset_timestep(bigint ntimestep) { for (int i = 0; i < nbin; i++) neigh_bin[i]->last_bin = -1; for (int i = 0; i < nstencil; i++) neigh_stencil[i]->last_stencil = -1; for (int i = 0; i < nlist; i++) { if (!neigh_pair[i]) continue; neigh_pair[i]->last_build = -1; } lastcall = -1; last_setup_bins = -1; } /* ---------------------------------------------------------------------- modify parameters of the pair-wise neighbor build ------------------------------------------------------------------------- */ void Neighbor::modify_params(int narg, char **arg) { int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"every") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); every = force->inumeric(FLERR,arg[iarg+1]); if (every <= 0) error->all(FLERR,"Illegal neigh_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"delay") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); delay = force->inumeric(FLERR,arg[iarg+1]); if (delay < 0) error->all(FLERR,"Illegal neigh_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"check") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); if (strcmp(arg[iarg+1],"yes") == 0) dist_check = 1; else if (strcmp(arg[iarg+1],"no") == 0) dist_check = 0; else error->all(FLERR,"Illegal neigh_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"once") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); if (strcmp(arg[iarg+1],"yes") == 0) build_once = 1; else if (strcmp(arg[iarg+1],"no") == 0) build_once = 0; else error->all(FLERR,"Illegal neigh_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"page") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); old_pgsize = pgsize; pgsize = force->inumeric(FLERR,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"one") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); old_oneatom = oneatom; oneatom = force->inumeric(FLERR,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"binsize") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); binsize_user = force->numeric(FLERR,arg[iarg+1]); if (binsize_user <= 0.0) binsizeflag = 0; else binsizeflag = 1; iarg += 2; } else if (strcmp(arg[iarg],"cluster") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); if (strcmp(arg[iarg+1],"yes") == 0) cluster_check = 1; else if (strcmp(arg[iarg+1],"no") == 0) cluster_check = 0; else error->all(FLERR,"Illegal neigh_modify command"); iarg += 2; } else if (strcmp(arg[iarg],"include") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); includegroup = group->find(arg[iarg+1]); if (includegroup < 0) error->all(FLERR,"Invalid group ID in neigh_modify command"); if (includegroup && (atom->firstgroupname == NULL || strcmp(arg[iarg+1],atom->firstgroupname) != 0)) error->all(FLERR, "Neigh_modify include group != atom_modify first group"); iarg += 2; } else if (strcmp(arg[iarg],"exclude") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command"); if (strcmp(arg[iarg+1],"type") == 0) { if (iarg+4 > narg) error->all(FLERR,"Illegal neigh_modify command"); if (nex_type == maxex_type) { maxex_type += EXDELTA; memory->grow(ex1_type,maxex_type,"neigh:ex1_type"); memory->grow(ex2_type,maxex_type,"neigh:ex2_type"); } ex1_type[nex_type] = force->inumeric(FLERR,arg[iarg+2]); ex2_type[nex_type] = force->inumeric(FLERR,arg[iarg+3]); nex_type++; iarg += 4; } else if (strcmp(arg[iarg+1],"group") == 0) { if (iarg+4 > narg) error->all(FLERR,"Illegal neigh_modify command"); if (nex_group == maxex_group) { maxex_group += EXDELTA; memory->grow(ex1_group,maxex_group,"neigh:ex1_group"); memory->grow(ex2_group,maxex_group,"neigh:ex2_group"); } ex1_group[nex_group] = group->find(arg[iarg+2]); ex2_group[nex_group] = group->find(arg[iarg+3]); if (ex1_group[nex_group] == -1 || ex2_group[nex_group] == -1) error->all(FLERR,"Invalid group ID in neigh_modify command"); nex_group++; iarg += 4; } else if (strcmp(arg[iarg+1],"molecule/inter") == 0 || strcmp(arg[iarg+1],"molecule/intra") == 0) { if (iarg+3 > narg) error->all(FLERR,"Illegal neigh_modify command"); if (atom->molecule_flag == 0) error->all(FLERR,"Neigh_modify exclude molecule " "requires atom attribute molecule"); if (nex_mol == maxex_mol) { maxex_mol += EXDELTA; memory->grow(ex_mol_group,maxex_mol,"neigh:ex_mol_group"); if (lmp->kokkos) grow_ex_mol_intra_kokkos(); else memory->grow(ex_mol_intra,maxex_mol,"neigh:ex_mol_intra"); } ex_mol_group[nex_mol] = group->find(arg[iarg+2]); if (ex_mol_group[nex_mol] == -1) error->all(FLERR,"Invalid group ID in neigh_modify command"); if (strcmp(arg[iarg+1],"molecule/intra") == 0) ex_mol_intra[nex_mol] = 1; else ex_mol_intra[nex_mol] = 0; nex_mol++; iarg += 3; } else if (strcmp(arg[iarg+1],"none") == 0) { nex_type = nex_group = nex_mol = 0; iarg += 2; } else error->all(FLERR,"Illegal neigh_modify command"); } else error->all(FLERR,"Illegal neigh_modify command"); } } /* ---------------------------------------------------------------------- remove the first group-group exclusion matching group1, group2 ------------------------------------------------------------------------- */ void Neighbor::exclusion_group_group_delete(int group1, int group2) { int m, mlast; for (m = 0; m < nex_group; m++) if (ex1_group[m] == group1 && ex2_group[m] == group2 ) break; mlast = m; if (mlast == nex_group) error->all(FLERR,"Unable to find group-group exclusion"); for (m = mlast+1; m < nex_group; m++) { ex1_group[m-1] = ex1_group[m]; ex2_group[m-1] = ex2_group[m]; ex1_bit[m-1] = ex1_bit[m]; ex2_bit[m-1] = ex2_bit[m]; } nex_group--; } /* ---------------------------------------------------------------------- return the value of exclude - used to check compatibility with GPU ------------------------------------------------------------------------- */ int Neighbor::exclude_setting() { return exclude; } /* ---------------------------------------------------------------------- return # of bytes of allocated memory ------------------------------------------------------------------------- */ bigint Neighbor::memory_usage() { bigint bytes = 0; bytes += memory->usage(xhold,maxhold,3); for (int i = 0; i < nlist; i++) if (lists[i]) bytes += lists[i]->memory_usage(); for (int i = 0; i < nstencil; i++) bytes += neigh_stencil[i]->memory_usage(); for (int i = 0; i < nbin; i++) bytes += neigh_bin[i]->memory_usage(); if (neigh_bond) bytes += neigh_bond->memory_usage(); if (neigh_angle) bytes += neigh_angle->memory_usage(); if (neigh_dihedral) bytes += neigh_dihedral->memory_usage(); if (neigh_improper) bytes += neigh_improper->memory_usage(); return bytes; } diff --git a/src/neighbor.h b/src/neighbor.h index 16a80b599..64bced229 100644 --- a/src/neighbor.h +++ b/src/neighbor.h @@ -1,374 +1,375 @@ /* -*- 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_NEIGHBOR_H #define LMP_NEIGHBOR_H #include "pointers.h" #include namespace LAMMPS_NS { class Neighbor : protected Pointers { public: int style; // 0,1,2 = nsq, bin, multi int every; // build every this many steps int delay; // delay build for this many steps int dist_check; // 0 = always build, 1 = only if 1/2 dist int ago; // how many steps ago neighboring occurred int pgsize; // size of neighbor page int oneatom; // max # of neighbors for one atom int includegroup; // only build pairwise lists for this group int build_once; // 1 if only build lists once per run double skin; // skin distance double cutneighmin; // min neighbor cutoff for all type pairs double cutneighmax; // max neighbor cutoff for all type pairs double cutneighmaxsq; // cutneighmax squared double **cutneighsq; // neighbor cutneigh sq for each type pair double **cutneighghostsq; // cutneigh sq for each ghost type pair double *cuttype; // for each type, max neigh cut w/ others double *cuttypesq; // cuttype squared double cut_inner_sq; // outer cutoff for inner neighbor list double cut_middle_sq; // outer cutoff for middle neighbor list double cut_middle_inside_sq; // inner cutoff for middle neighbor list int binsizeflag; // user-chosen bin size double binsize_user; // set externally by some accelerator pkgs bigint ncalls; // # of times build has been called bigint ndanger; // # of dangerous builds bigint lastcall; // timestep of last neighbor::build() call // geometry and static info, used by other Neigh classes double *bboxlo,*bboxhi; // ptrs to full domain bounding box // different for orthog vs triclinic double *zeroes; // vector of zeroes for shear history init // exclusion info, used by NeighPair int exclude; // 0 if no type/group exclusions, 1 if yes int nex_type; // # of entries in type exclusion list int *ex1_type,*ex2_type; // pairs of types to exclude int **ex_type; // 2d array of excluded type pairs int nex_group; // # of entries in group exclusion list int *ex1_group,*ex2_group; // pairs of group #'s to exclude int *ex1_bit,*ex2_bit; // pairs of group bits to exclude int nex_mol; // # of entries in molecule exclusion list int *ex_mol_group; // molecule group #'s to exclude int *ex_mol_bit; // molecule group bits to exclude int *ex_mol_intra; // 0 = exclude if in 2 molecules (inter) // 1 = exclude if in same molecule (intra) // special info, used by NeighPair int special_flag[4]; // flags for 1-2, 1-3, 1-4 neighbors // cluster setting, used by NeighTopo int cluster_check; // 1 if check bond/angle/etc satisfies minimg // pairwise neighbor lists and corresponding requests int nlist; // # of pairwise neighbor lists int nrequest; // # of requests, same as nlist int old_nrequest; // # of requests for previous run class NeighList **lists; class NeighRequest **requests; // from Pair,Fix,Compute,Command classes class NeighRequest **old_requests; // copy of requests to compare to // data from topology neighbor lists int nbondlist; // list of bonds to compute int **bondlist; int nanglelist; // list of angles to compute int **anglelist; int ndihedrallist; // list of dihedrals to compute int **dihedrallist; int nimproperlist; // list of impropers to compute int **improperlist; // public methods Neighbor(class LAMMPS *); virtual ~Neighbor(); virtual void init(); int request(void *, int instance=0); int decide(); // decide whether to build or not virtual int check_distance(); // check max distance moved since last build void setup_bins(); // setup bins based on box and cutoff virtual void build(int topoflag=1); // build all perpetual neighbor lists virtual void build_topology(); // pairwise topology neighbor lists void build_one(class NeighList *list, int preflag=0); // create a one-time pairwise neigh list void set(int, char **); // set neighbor style and skin distance void reset_timestep(bigint); // reset of timestep counter void modify_params(int, char**); // modify params that control builds void exclusion_group_group_delete(int, int); // rm a group-group exclusion int exclude_setting(); // return exclude value to accelerator pkg + class NeighRequest *find_request(void *); // find a neighbor request bigint memory_usage(); protected: int me,nprocs; int firsttime; // flag for calling init_styles() only once int dimension; // 2/3 for 2d/3d int triclinic; // 0 if domain is orthog, 1 if triclinic int newton_pair; // 0 if newton off for pairwise, 1 if on int must_check; // 1 if must check other classes to reneigh int restart_check; // 1 if restart enabled, 0 if no int fix_check; // # of fixes that induce reneigh int *fixchecklist; // which fixes to check bigint last_setup_bins; // step of last neighbor::setup_bins() call double triggersq; // trigger = build when atom moves this dist double **xhold; // atom coords at last neighbor build int maxhold; // size of xhold array int boxcheck; // 1 if need to store box size double boxlo_hold[3],boxhi_hold[3]; // box size at last neighbor build double corners_hold[8][3]; // box corners at last neighbor build double (*corners)[3]; // ptr to 8 corners of triclinic box double inner[2],middle[2]; // rRESPA cutoffs for extra lists int old_style,old_triclinic; // previous run info int old_pgsize,old_oneatom; // used to avoid re-creating neigh lists int nstencil_perpetual; // # of perpetual NeighStencil classes int npair_perpetual; // #x of perpetual NeighPair classes int *slist; // indices of them in neigh_stencil int *plist; // indices of them in neigh_pair int maxex_type; // max # in exclusion type list int maxex_group; // max # in exclusion group list int maxex_mol; // max # in exclusion molecule list int maxatom; // max size of atom-based NeighList arrays int maxrequest; // max size of NeighRequest list int maxwt; // max weighting factor applied + 1 // info for other Neigh classes: NBin,NStencil,NPair,NTopo int nbin,nstencil; int nbclass,nsclass,npclass; int bondwhich,anglewhich,dihedralwhich,improperwhich; typedef class NBin *(*BinCreator)(class LAMMPS *); BinCreator *binclass; char **binnames; int *binmasks; class NBin **neigh_bin; typedef class NStencil *(*StencilCreator)(class LAMMPS *); StencilCreator *stencilclass; char **stencilnames; int *stencilmasks; class NStencil **neigh_stencil; typedef class NPair *(*PairCreator)(class LAMMPS *); PairCreator *pairclass; char **pairnames; int *pairmasks; class NPair **neigh_pair; class NTopo *neigh_bond; class NTopo *neigh_angle; class NTopo *neigh_dihedral; class NTopo *neigh_improper; // internal methods // including creator methods for Nbin,Nstencil,Npair instances void init_styles(); int init_pair(); virtual void init_topology(); void morph_other(); void morph_skip(); void morph_granular(); void morph_halffull(); void morph_copy(); void print_pairwise_info(); void requests_new2old(); int choose_bin(class NeighRequest *); int choose_stencil(class NeighRequest *); int choose_pair(class NeighRequest *); template static NBin *bin_creator(class LAMMPS *); template static NStencil *stencil_creator(class LAMMPS *); template static NPair *pair_creator(class LAMMPS *); // dummy functions provided by NeighborKokkos, called in init() // otherwise NeighborKokkos would have to overwrite init() int copymode; virtual void init_cutneighsq_kokkos(int) {} virtual void create_kokkos_list(int) {} virtual void init_ex_type_kokkos(int) {} virtual void init_ex_bit_kokkos() {} virtual void init_ex_mol_bit_kokkos() {} virtual void grow_ex_mol_intra_kokkos() {} }; namespace NeighConst { static const int NB_INTEL = 1<<0; static const int NB_KOKKOS_DEVICE = 1<<1; static const int NB_KOKKOS_HOST = 1<<2; static const int NB_SSA = 1<<3; static const int NS_BIN = 1<<0; static const int NS_MULTI = 1<<1; static const int NS_HALF = 1<<2; static const int NS_FULL = 1<<3; static const int NS_2D = 1<<4; static const int NS_3D = 1<<5; static const int NS_NEWTON = 1<<6; static const int NS_NEWTOFF = 1<<7; static const int NS_ORTHO = 1<<8; static const int NS_TRI = 1<<9; static const int NS_GHOST = 1<<10; static const int NS_SSA = 1<<11; static const int NP_NSQ = 1<<0; static const int NP_BIN = 1<<1; static const int NP_MULTI = 1<<2; static const int NP_HALF = 1<<3; static const int NP_FULL = 1<<4; static const int NP_ORTHO = 1<<5; static const int NP_TRI = 1<<6; static const int NP_ATOMONLY = 1<<7; static const int NP_MOLONLY = 1<<8; static const int NP_NEWTON = 1<<9; static const int NP_NEWTOFF = 1<<10; static const int NP_GHOST = 1<<11; static const int NP_SIZE = 1<<12; static const int NP_ONESIDE = 1<<13; static const int NP_RESPA = 1<<14; static const int NP_BOND = 1<<15; static const int NP_OMP = 1<<16; static const int NP_INTEL = 1<<17; static const int NP_KOKKOS_DEVICE = 1<<18; static const int NP_KOKKOS_HOST = 1<<19; static const int NP_SSA = 1<<20; static const int NP_COPY = 1<<21; static const int NP_SKIP = 1<<22; static const int NP_HALF_FULL = 1<<23; static const int NP_OFF2ON = 1<<24; } } #endif /* ERROR/WARNING messages: E: Neighbor delay must be 0 or multiple of every setting The delay and every parameters set via the neigh_modify command are inconsistent. If the delay setting is non-zero, then it must be a multiple of the every setting. E: Neighbor page size must be >= 10x the one atom setting This is required to prevent wasting too much memory. E: Invalid atom type in neighbor exclusion list Atom types must range from 1 to Ntypes inclusive. W: Neighbor exclusions used with KSpace solver may give inconsistent Coulombic energies This is because excluding specific pair interactions also excludes them from long-range interactions which may not be the desired effect. The special_bonds command handles this consistently by insuring excluded (or weighted) 1-2, 1-3, 1-4 interactions are treated consistently by both the short-range pair style and the long-range solver. This is not done for exclusions of charged atom pairs via the neigh_modify exclude command. E: Neighbor include group not allowed with ghost neighbors This is a current restriction within LAMMPS. E: Neighbor multi not yet enabled for ghost neighbors This is a current restriction within LAMMPS. E: Neighbor multi not yet enabled for granular Self-explanatory. E: Neighbor multi not yet enabled for rRESPA Self-explanatory. E: Too many local+ghost atoms for neighbor list The number of nlocal + nghost atoms on a processor is limited by the size of a 32-bit integer with 2 bits removed for masking 1-2, 1-3, 1-4 neighbors. E: Trying to build an occasional neighbor list before initialization completed This is not allowed. Source code caller needs to be modified. E: Domain too large for neighbor bins The domain has become extremely large so that neighbor bins cannot be used. Most likely, one or more atoms have been blown out of the simulation box to a great distance. E: Cannot use neighbor bins - box size << cutoff Too many neighbor bins will be created. This typically happens when the simulation box is very small in some dimension, compared to the neighbor cutoff. Use the "nsq" style instead of "bin" style. E: Too many neighbor bins This is likely due to an immense simulation box that has blown up to a large size. 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: Invalid group ID in neigh_modify command A group ID used in the neigh_modify command does not exist. E: Neigh_modify include group != atom_modify first group Self-explanatory. E: Neigh_modify exclude molecule requires atom attribute molecule Self-explanatory. */ diff --git a/src/pair_coul_streitz.h b/src/pair_coul_streitz.h index 5f02d29c1..8e713997f 100644 --- a/src/pair_coul_streitz.h +++ b/src/pair_coul_streitz.h @@ -1,137 +1,137 @@ -/* ---------------------------------------------------------------------- +/* -*- 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(coul/streitz,PairCoulStreitz) #else #ifndef LMP_PAIR_COUL_Streitz_H #define LMP_PAIR_COUL_Streitz_H #include "pair.h" namespace LAMMPS_NS { class PairCoulStreitz : public Pair { public: PairCoulStreitz(class LAMMPS *); virtual ~PairCoulStreitz(); virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); void init_style(); double init_one(int, int); double memory_usage(); virtual void *extract(const char *, int &); protected: struct Param { double chi, eta, gamma, zeta, zcore; int ielement; }; int nmax; int nelements; // # of unique elements char **elements; // names of unique elements int *elem2param; // mapping from element triplets to parameters int *map; // mapping from atom types to elements int nparams; // # of stored parameter sets int maxparam; // max # of parameter sets double precision; Param *params; // parameter set for an I-J-K interaction // Kspace parameters int kspacetype; double cut_coul, cut_coulsq; double *cut_respa; double **scale; // Wolf double g_wolf, woself, dwoself; // Ewald double g_ewald; // QEq double *qeq_x, *qeq_j, *qeq_g, *qeq_z, *qeq_c; void allocate(); virtual void read_file(char *); void setup_params(); double self(Param *, double); void coulomb_integral_wolf(double, double, double, double &, double &, double &, double &); void wolf_sum(double, double, double, double, double, double, double, double, double &, double &); void coulomb_integral_ewald(double, double, double, double &, double &, double &, double &); void ewald_sum(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: Incorrect args for pair coefficients Self-explanatory. Check the input script or data file. E: Pair style coul/streitz requires atom attribute q Self-explanatory. E: Pair style requires a KSpace style No kspace style is defined. 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: Cannot open coul/streitz potential file %s The specified coul/streitz potential file cannot be opened. Check that the path and name are correct. E: Incorrect format in coul/streitz potential file Incorrect number of words per line in the potential file. E: Illegal coul/streitz parameter One or more of the coefficients defined in the potential file is invalid. E: Potential file has duplicate entry The potential file has more than one entry for the same element. E: Potential file is missing an entry The potential file does not have a needed entry. */