diff --git a/doc/src/Section_commands.txt b/doc/src/Section_commands.txt index 0d46a0142..da1121e81 100644 --- a/doc/src/Section_commands.txt +++ b/doc/src/Section_commands.txt @@ -1,1249 +1,1249 @@ "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, "temper/npt"_temper_npt.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, "latte"_fix_latte.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, "edpd/source"_fix_dpd_source.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, "mvv/dpd"_fix_mvv_dpd.html, "mvv/edpd"_fix_mvv_dpd.html, "mvv/tdpd"_fix_mvv_dpd.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, "tdpd/source"_fix_dpd_source.html, "temp/rescale/eff"_fix_temp_rescale_eff.html, "ti/spring"_fix_ti_spring.html, "ttm/mod"_fix_ttm.html, "wall/ees"_fix_wall_ees.html, "wall/region/ees"_fix_wall_ees.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. "aggregate/atom"_compute_cluster_atom.html, "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, "fragment/atom"_compute_cluster_atom.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, "edpd/temp/atom"_compute_edpd_temp_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, "tdpd/cc/atom"_compute_tdpd_cc_atom.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 (oi)"_pair_airebo.html, "airebo/morse (oi)"_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 (giko)"_pair_buck.html, +"buck/coul/cut (giko)"_pair_buck.html, +"buck/coul/long (giko)"_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 (gio)"_pair_dpd.html, "dpd/tstat (go)"_pair_dpd.html, "dsmc"_pair_dsmc.html, -"eam (gkiot)"_pair_eam.html, -"eam/alloy (gkiot)"_pair_eam.html, -"eam/fs (gkiot)"_pair_eam.html, +"eam (gikot)"_pair_eam.html, +"eam/alloy (gikot)"_pair_eam.html, +"eam/fs (gikot)"_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 (kio)"_pair_charmm.html, +"lj/charmm/coul/charmm (iko)"_pair_charmm.html, "lj/charmm/coul/charmm/implicit (ko)"_pair_charmm.html, -"lj/charmm/coul/long (gkio)"_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 (oi)"_pair_airebo.html, "resquared (go)"_pair_resquared.html, "snap"_pair_snap.html, "soft (go)"_pair_soft.html, -"sw (gkio)"_pair_sw.html, +"sw (giko)"_pair_sw.html, "table (gko)"_pair_table.html, -"tersoff (gkio)"_pair_tersoff.html, +"tersoff (giko)"_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, "edpd"_pair_meso.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, "mdpd"_pair_meso.html, "mdpd/rhosum"_pair_meso.html, "meam/c"_pair_meam.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, "tdpd"_pair_meso.html, "tersoff/table (o)"_pair_tersoff.html, "thole"_pair_thole.html, "tip4p/long/soft (o)"_pair_lj_soft.html :tb(c=4,ea=c) :line Bond_style potentials :h4 See the "bond_style"_bond_style.html command for an overview of bond potentials. Click on the style itself for a full description. Some of the styles have accelerated versions, which can be used if LAMMPS is built with the "appropriate accelerated package"_Section_accelerate.html. This is indicated by additional letters in parenthesis: g = GPU, i = USER-INTEL, k = KOKKOS, o = USER-OMP, t = OPT. "none"_bond_none.html, "zero"_bond_zero.html, "hybrid"_bond_hybrid.html, "class2 (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, +"charmm (iko)"_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, +"fourier (io)"_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, +"harmonic (iko)"_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/dump_modify.txt b/doc/src/dump_modify.txt index 38d9aad4d..db727c2d4 100644 --- a/doc/src/dump_modify.txt +++ b/doc/src/dump_modify.txt @@ -1,1008 +1,1012 @@ "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c :link(lws,http://lammps.sandia.gov) :link(ld,Manual.html) :link(lc,Section_commands.html#comm) :line dump_modify command :h3 [Syntax:] dump_modify dump-ID keyword values ... :pre dump-ID = ID of dump to modify :ulb,l one or more keyword/value pairs may be appended :l these keywords apply to various dump styles :l keyword = {append} or {at} or {buffer} or {element} or {every} or {fileper} or {first} or {flush} or {format} or {image} or {label} or {nfile} or {pad} or {precision} or {region} or {scale} or {sort} or {thresh} or {unwrap} :l {append} arg = {yes} or {no} {at} arg = N N = index of frame written upon first dump - only available after "append yes" {buffer} arg = {yes} or {no} {element} args = E1 E2 ... EN, where N = # of atom types E1,...,EN = element name, e.g. C or Fe or Ga {every} arg = N N = dump every this many timesteps N can be a variable (see below) {fileper} arg = Np Np = write one file for every this many processors {first} arg = {yes} or {no} {format} args = {line} string, {int} string, {float} string, M string, or {none} string = C-style format string M = integer from 1 to N, where N = # of per-atom quantities being output {flush} arg = {yes} or {no} {image} arg = {yes} or {no} {label} arg = string string = character string (e.g. BONDS) to use in header of dump local file {nfile} arg = Nf Nf = write this many files, one from each of Nf processors {pad} arg = Nchar = # of characters to convert timestep to {pbc} arg = {yes} or {no} = remap atoms via periodic boundary conditions {precision} arg = power-of-10 value from 10 to 1000000 {region} arg = region-ID or "none" {scale} arg = {yes} or {no} {sfactor} arg = coordinate scaling factor (> 0.0) {thermo} arg = {yes} or {no} {tfactor} arg = time scaling factor (> 0.0) {sort} arg = {off} or {id} or N or -N off = no sorting of per-atom lines within a snapshot id = sort per-atom lines by atom ID N = sort per-atom lines in ascending order by the Nth column -N = sort per-atom lines in descending order by the Nth column {thresh} args = attribute operator value attribute = same attributes (x,fy,etotal,sxx,etc) used by dump custom style operator = "<" or "<=" or ">" or ">=" or "==" or "!=" or "|^" value = numeric value to compare to, or LAST these 3 args can be replaced by the word "none" to turn off thresholding {unwrap} arg = {yes} or {no} :pre these keywords apply only to the {image} and {movie} "styles"_dump_image.html :l keyword = {acolor} or {adiam} or {amap} or {backcolor} or {bcolor} or {bdiam} or {boxcolor} or {color} or {bitrate} or {framerate} :l {acolor} args = type color type = atom type or range of types (see below) color = name of color or color1/color2/... {adiam} args = type diam type = atom type or range of types (see below) diam = diameter of atoms of that type (distance units) {amap} args = lo hi style delta N entry1 entry2 ... entryN lo = number or {min} = lower bound of range of color map hi = number or {max} = upper bound of range of color map style = 2 letters = "c" or "d" or "s" plus "a" or "f" "c" for continuous "d" for discrete "s" for sequential "a" for absolute "f" for fractional delta = binsize (only used for style "s", otherwise ignored) binsize = range is divided into bins of this width N = # of subsequent entries entry = value color (for continuous style) value = number or {min} or {max} = single value within range color = name of color used for that value entry = lo hi color (for discrete style) lo/hi = number or {min} or {max} = lower/upper bound of subset of range color = name of color used for that subset of values entry = color (for sequential style) color = name of color used for a bin of values {backcolor} arg = color color = name of color for background {bcolor} args = type color type = bond type or range of types (see below) color = name of color or color1/color2/... {bdiam} args = type diam type = bond type or range of types (see below) diam = diameter of bonds of that type (distance units) {boxcolor} arg = color color = name of color for simulation box lines and processor sub-domain lines {color} args = name R G B name = name of color R,G,B = red/green/blue numeric values from 0.0 to 1.0 {bitrate} arg = rate rate = target bitrate for movie in kbps {framerate} arg = fps fps = frames per second for movie :pre :ule [Examples:] dump_modify 1 format line "%d %d %20.15g %g %g" scale yes dump_modify 1 format float %20.15g scale yes dump_modify myDump image yes scale no flush yes dump_modify 1 region mySphere thresh x < 0.0 thresh epair >= 3.2 dump_modify xtcdump precision 10000 sfactor 0.1 dump_modify 1 every 1000 nfile 20 dump_modify 1 every v_myVar dump_modify 1 amap min max cf 0.0 3 min green 0.5 yellow max blue boxcolor red :pre [Description:] Modify the parameters of a previously defined dump command. Not all parameters are relevant to all dump styles. As explained on the "dump"_dump.html doc page, the {atom/mpiio}, {custom/mpiio}, and {xyz/mpiio} dump styles are identical in command syntax and in the format of the dump files they create, to the corresponding styles without "mpiio", except the single dump file they produce is written in parallel via the MPI-IO library. Thus if a dump_modify option below is valid for the {atom} style, it is also valid for the {atom/mpiio} style, and similarly for the other styles which allow for use of MPI-IO. :line :line These keywords apply to various dump styles, including the "dump image"_dump_image.html and "dump movie"_dump_image.html styles. The description gives details. :line The {append} keyword applies to all dump styles except {cfg} and {xtc} and {dcd}. It also applies only to text output files, not to binary or gzipped or image/movie files. If specified as {yes}, then dump snapshots are appended to the end of an existing dump file. If specified as {no}, then a new dump file will be created which will -overwrite an existing file with the same name. If the {at} option is present -({netcdf} only), then the frame to append to can be specified. Negative values -are counted from the end of the file. This keyword can only take effect if the -dump_modify command is used after the "dump"_dump.html command, but before the -first command that causes dump snapshots to be output, e.g. a "run"_run.html or -"minimize"_minimize.html command. Once the dump file has been opened, this -keyword has no further effect. +overwrite an existing file with the same name. + +:line + +The {at} keyword only applies to the {netcdf} dump style. It can only +be used if the {append yes} keyword is also used. The {N} argument is +the index of which frame to append to. A negative value can be +specified for {N}, which means a frame counted from the end of the +file. The {at} keyword can only be used if the dump_modify command is +before the first command that causes dump snapshots to be output, +e.g. a "run"_run.html or "minimize"_minimize.html command. Once the +dump file has been opened, this keyword has no further effect. :line The {buffer} keyword applies only to dump styles {atom}, {cfg}, {custom}, {local}, and {xyz}. It also applies only to text output files, not to binary or gzipped files. If specified as {yes}, which is the default, then each processor writes its output into an internal text buffer, which is then sent to the processor(s) which perform file writes, and written by those processors(s) as one large chunk of text. If specified as {no}, each processor sends its per-atom data in binary format to the processor(s) which perform file wirtes, and those processor(s) format and write it line by line into the output file. The buffering mode is typically faster since each processor does the relatively expensive task of formatting the output for its own atoms. However it requires about twice the memory (per processor) for the extra buffering. :line The {element} keyword applies only to the dump {cfg}, {xyz}, and {image} styles. It associates element names (e.g. H, C, Fe) with LAMMPS atom types. See the list of element names at the bottom of this page. In the case of dump {cfg}, this allows the "AtomEye"_atomeye visualization package to read the dump file and render atoms with the appropriate size and color. In the case of dump {image}, the output images will follow the same "AtomEye"_atomeye convention. An element name is specified for each atom type (1 to Ntype) in the simulation. The same element name can be given to multiple atom types. In the case of {xyz} format dumps, there are no restrictions to what label can be used as an element name. Any whitespace separated text will be accepted. :link(atomeye,http://mt.seas.upenn.edu/Archive/Graphics/A) :line The {every} keyword changes the dump frequency originally specified by the "dump"_dump.html command to a new value. The every keyword can be specified in one of two ways. It can be a numeric value in which case it must be > 0. Or it can be an "equal-style variable"_variable.html, which should be specified as v_name, where name is the variable name. In this case, the variable is evaluated at the beginning of a run to determine the next timestep at which a dump snapshot will be written out. On that timestep the variable will be evaluated again to determine the next timestep, etc. Thus the variable should return timestep values. See the stagger() and logfreq() and stride() math functions for "equal-style variables"_variable.html, as examples of useful functions to use in this context. Other similar math functions could easily be added as options for "equal-style variables"_variable.html. Also see the next() function, which allows use of a file-style variable which reads successive values from a file, each time the variable is evaluated. Used with the {every} keyword, if the file contains a list of ascending timesteps, you can output snapshots whenever you wish. Note that when using the variable option with the {every} keyword, you need to use the {first} option if you want an initial snapshot written to the dump file. The {every} keyword cannot be used with the dump {dcd} style. For example, the following commands will write snapshots at timesteps 0,10,20,30,100,200,300,1000,2000,etc: variable s equal logfreq(10,3,10) dump 1 all atom 100 tmp.dump dump_modify 1 every v_s first yes :pre The following commands would write snapshots at the timesteps listed in file tmp.times: variable f file tmp.times variable s equal next(f) dump 1 all atom 100 tmp.dump dump_modify 1 every v_s :pre NOTE: When using a file-style variable with the {every} keyword, the file of timesteps must list a first timestep that is beyond the current timestep (e.g. it cannot be 0). And it must list one or more timesteps beyond the length of the run you perform. This is because the dump command will generate an error if the next timestep it reads from the file is not a value greater than the current timestep. Thus if you wanted output on steps 0,15,100 of a 100-timestep run, the file should contain the values 15,100,101 and you should also use the dump_modify first command. Any final value > 100 could be used in place of 101. :line The {first} keyword determines whether a dump snapshot is written on the very first timestep after the dump command is invoked. This will always occur if the current timestep is a multiple of N, the frequency specified in the "dump"_dump.html command, including timestep 0. But if this is not the case, a dump snapshot will only be written if the setting of this keyword is {yes}. If it is {no}, which is the default, then it will not be written. :line The {flush} keyword determines whether a flush operation is invoked after a dump snapshot is written to the dump file. A flush insures the output in that file is current (no buffering by the OS), even if LAMMPS halts before the simulation completes. Flushes cannot be performed with dump style {xtc}. :line The {format} keyword can be used to change the default numeric format output by the text-based dump styles: {atom}, {custom}, {cfg}, and {xyz} styles, and their MPIIO variants. Only the {line} or {none} options can be used with the {atom} and {xyz} styles. All the specified format strings are C-style formats, e.g. as used by the C/C++ printf() command. The {line} keyword takes a single argument which is the format string for an entire line of output for each atom (do not include a trailing "\n"), with N fields, which you must enclose in quotes if it is more than one field. The {int} and {float} keywords take a single format argument and are applied to all integer or floating-point quantities output. The setting for {M string} also takes a single format argument which is used for the Mth value output in each line, e.g. the 5th column is output in high precision for "format 5 %20.15g". NOTE: When using the {line} keyword for the {cfg} style, the first two fields (atom ID and type) are not actually written into the CFG file, however you must include formats for them in the format string. The {format} keyword can be used multiple times. The precedence is that for each value in a line of output, the {M} format (if specified) is used, else the {int} or {float} setting (if specified) is used, else the {line} setting (if specified) for that value is used, else the default setting is used. A setting of {none} clears all previous settings, reverting all values to their default format. NOTE: Atom and molecule IDs are stored internally as 4-byte or 8-byte signed integers, depending on how LAMMPS was compiled. When specifying the {format int} option you can use a "%d"-style format identifier in the format string and LAMMPS will convert this to the corresponding 8-byte form it it is needed when outputting those values. However, when specifying the {line} option or {format M string} option for those values, you should specify a format string appropriate for an 8-byte signed integer, e.g. one with "%ld", if LAMMPS was compiled with the -DLAMMPS_BIGBIG option for 8-byte IDs. NOTE: Any value written to a text-based dump file that is a per-atom quantity calculated by a "compute"_compute.html or "fix"_fix.html is stored internally as a floating-point value. If the value is actually an integer and you wish it to appear in the text dump file as a (large) integer, then you need to use an appropriate format. For example, these commands: compute 1 all property/local batom1 batom2 dump 1 all local 100 tmp.bonds index c_1\[1\] c_1\[2\] dump_modify 1 format "%d %0.0f %0.0f" :pre will output the two atom IDs for atoms in each bond as integers. If the dump_modify command were omitted, they would appear as floating-point values, assuming they were large integers (more than 6 digits). The "index" keyword should use the "%d" format since it is not generated by a compute or fix, and is stored internally as an integer. :line The {fileper} keyword is documented below with the {nfile} keyword. :line The {image} keyword applies only to the dump {atom} style. If the image value is {yes}, 3 flags are appended to each atom's coords which are the absolute box image of the atom in each dimension. For example, an x image flag of -2 with a normalized coord of 0.5 means the atom is in the center of the box, but has passed thru the box boundary 2 times and is really 2 box lengths to the left of its current coordinate. Note that for dump style {custom} these various values can be printed in the dump file by using the appropriate atom attributes in the dump command itself. :line The {label} keyword applies only to the dump {local} style. When it writes local information, such as bond or angle topology to a dump file, it will use the specified {label} to format the header. By default this includes 2 lines: ITEM: NUMBER OF ENTRIES ITEM: ENTRIES ... :pre The word "ENTRIES" will be replaced with the string specified, e.g. BONDS or ANGLES. :line The {nfile} or {fileper} keywords can be used in conjunction with the "%" wildcard character in the specified dump file name, for all dump styles except the {dcd}, {image}, {movie}, {xtc}, and {xyz} styles (for which "%" is not allowed). As explained on the "dump"_dump.html command doc page, the "%" character causes the dump file to be written in pieces, one piece for each of P processors. By default P = the number of processors the simulation is running on. The {nfile} or {fileper} keyword can be used to set P to a smaller value, which can be more efficient when running on a large number of processors. The {nfile} keyword sets P to the specified Nf value. For example, if Nf = 4, and the simulation is running on 100 processors, 4 files will be written, by processors 0,25,50,75. Each will collect information from itself and the next 24 processors and write it to a dump file. For the {fileper} keyword, the specified value of Np means write one file for every Np processors. For example, if Np = 4, every 4th processor (0,4,8,12,etc) will collect information from itself and the next 3 processors and write it to a dump file. :line The {pad} keyword only applies when the dump filename is specified with a wildcard "*" character which becomes the timestep. If {pad} is 0, which is the default, the timestep is converted into a string of unpadded length, e.g. 100 or 12000 or 2000000. When {pad} is specified with {Nchar} > 0, the string is padded with leading zeroes so they are all the same length = {Nchar}. For example, pad 7 would yield 0000100, 0012000, 2000000. This can be useful so that post-processing programs can easily read the files in ascending timestep order. :line The {pbc} keyword applies to all the dump styles. As explained on the "dump"_dump.html doc page, atom coordinates in a dump file may be slightly outside the simulation box. This is because periodic boundary conditions are enforced only on timesteps when neighbor lists are rebuilt, which will not typically coincide with the timesteps dump snapshots are written. If the setting of this keyword is set to {yes}, then all atoms will be remapped to the periodic box before the snapshot is written, then restored to their original position. If it is set to {no} they will not be. The {no} setting is the default because it requires no extra computation. :line The {precision} keyword only applies to the dump {xtc} style. A specified value of N means that coordinates are stored to 1/N nanometer accuracy, e.g. for N = 1000, the coordinates are written to 1/1000 nanometer accuracy. :line The {sfactor} and {tfactor} keywords only apply to the dump {xtc} style. They allow customization of the unit conversion factors used when writing to XTC files. By default they are initialized for whatever "units"_units.html style is being used, to write out coordinates in nanometers and time in picoseconds. I.e. for {real} units, LAMMPS defines {sfactor} = 0.1 and {tfactor} = 0.001, since the Angstroms and fmsec used by {real} units are 0.1 nm and 0.001 psec respectively. If you are using a units system with distance and time units far from nm and psec, you may wish to write XTC files with different units, since the compression algorithm used in XTC files is most effective when the typical magnitude of position data is between 10.0 and 0.1. :line The {thermo} keyword ({netcdf} only) triggers writing of "thermo"_thermo.html information to the dump file alongside per-atom data. The data included in the dump file is identical to the data specified by "thermo_style"_thermo_style.html. :line The {region} keyword only applies to the dump {custom}, {cfg}, {image}, and {movie} styles. If specified, only atoms in the region will be written to the dump file or included in the image/movie. Only one region can be applied as a filter (the last one specified). See the "region"_region.html command for more details. Note that a region can be defined as the "inside" or "outside" of a geometric shape, and it can be the "union" or "intersection" of a series of simpler regions. :line The {scale} keyword applies only to the dump {atom} style. A scale value of {yes} means atom coords are written in normalized units from 0.0 to 1.0 in each box dimension. If the simulation box is triclinic (tilted), then all atom coords will still be between 0.0 and 1.0. A value of {no} means they are written in absolute distance units (e.g. Angstroms or sigma). :line The {sort} keyword determines whether lines of per-atom output in a snapshot are sorted or not. A sort value of {off} means they will typically be written in indeterminate order, either in serial or parallel. This is the case even in serial if the "atom_modify sort"_atom_modify.html option is turned on, which it is by default, to improve performance. A sort value of {id} means sort the output by atom ID. A sort value of N or -N means sort the output by the value in the Nth column of per-atom info in either ascending or descending order. The dump {local} style cannot be sorted by atom ID, since there are typically multiple lines of output per atom. Some dump styles, such as {dcd} and {xtc}, require sorting by atom ID to format the output file correctly. If multiple processors are writing the dump file, via the "%" wildcard in the dump filename, then sorting cannot be performed. NOTE: Unless it is required by the dump style, sorting dump file output requires extra overhead in terms of CPU and communication cost, as well as memory, versus unsorted output. :line The {thresh} keyword only applies to the dump {custom}, {cfg}, {image}, and {movie} styles. Multiple thresholds can be specified. Specifying {none} turns off all threshold criteria. If thresholds are specified, only atoms whose attributes meet all the threshold criteria are written to the dump file or included in the image. The possible attributes that can be tested for are the same as those that can be specified in the "dump custom"_dump.html command, with the exception of the {element} attribute, since it is not a numeric value. Note that a different attributes can be used than those output by the "dump custom"_dump.html command. E.g. you can output the coordinates and stress of atoms whose energy is above some threshold. If an atom-style variable is used as the attribute, then it can produce continuous numeric values or effective Boolean 0/1 values which may be useful for the comparison operator. Boolean values can be generated by variable formulas that use comparison or Boolean math operators or special functions like gmask() and rmask() and grmask(). See the "variable"_variable.html command doc page for details. The specified value must be a simple numeric value or the word LAST. If LAST is used, it refers to the value of the attribute the last time the dump command was invoked to produce a snapshot. This is a way to only dump atoms whose attribute has changed (or not changed). Three examples follow. dump_modify ... thresh ix != LAST :pre This will dump atoms which have crossed the periodic x boundary of the simulation box since the last dump. (Note that atoms that crossed once and then crossed back between the two dump timesteps would not be included.) region foo sphere 10 20 10 15 variable inregion atom rmask(foo) dump_modify ... thresh v_inregion |^ LAST This will dump atoms which crossed the boundary of the spherical region since the last dump. variable charge atom "(q > 0.5) || (q < -0.5)" dump_modify ... thresh v_charge |^ LAST This will dump atoms whose charge has changed from an absolute value less than 1/2 to greater than 1/2 (or vice versa) since the last dump. E.g. due to reactions and subsequent charge equilibration in a reactive force field. The choice of operators listed above are the usual comparison operators. The XOR operation (exclusive or) is also included as "|^". In this context, XOR means that if either the attribute or value is 0.0 and the other is non-zero, then the result is "true" and the threshold criterion is met. Otherwise it is not met. :line The {unwrap} keyword only applies to the dump {dcd} and {xtc} styles. If set to {yes}, coordinates will be written "unwrapped" by the image flags for each atom. Unwrapped means that if the atom has passed thru a periodic boundary one or more times, the value is printed for what the coordinate would be if it had not been wrapped back into the periodic box. Note that these coordinates may thus be far outside the box size stored with the snapshot. :line :line These keywords apply only to the "dump image"_dump_image.html and "dump movie"_dump_image.html styles. Any keyword that affects an image, also affects a movie, since the movie is simply a collection of images. Some of the keywords only affect the "dump movie"_dump_image.html style. The descriptions give details. :line The {acolor} keyword can be used with the "dump image"_dump_image.html command, when its atom color setting is {type}, to set the color that atoms of each type will be drawn in the image. The specified {type} should be an integer from 1 to Ntypes = the number of atom types. A wildcard asterisk can be used in place of or in conjunction with the {type} argument to specify a range of atom types. This takes the form "*" or "*n" or "n*" or "m*n". If N = the number of atom types, then an asterisk with no numeric values means all types from 1 to N. A leading asterisk means all types from 1 to n (inclusive). A trailing asterisk means all types from n to N (inclusive). A middle asterisk means all types from m to n (inclusive). The specified {color} can be a single color which is any of the 140 pre-defined colors (see below) or a color name defined by the dump_modify color option. Or it can be two or more colors separated by a "/" character, e.g. red/green/blue. In the former case, that color is assigned to all the specified atom types. In the latter case, the list of colors are assigned in a round-robin fashion to each of the specified atom types. :line The {adiam} keyword can be used with the "dump image"_dump_image.html command, when its atom diameter setting is {type}, to set the size that atoms of each type will be drawn in the image. The specified {type} should be an integer from 1 to Ntypes. As with the {acolor} keyword, a wildcard asterisk can be used as part of the {type} argument to specify a range of atomt types. The specified {diam} is the size in whatever distance "units"_units.html the input script is using, e.g. Angstroms. :line The {amap} keyword can be used with the "dump image"_dump_image.html command, with its {atom} keyword, when its atom setting is an atom-attribute, to setup a color map. The color map is used to assign a specific RGB (red/green/blue) color value to an individual atom when it is drawn, based on the atom's attribute, which is a numeric value, e.g. its x-component of velocity if the atom-attribute "vx" was specified. The basic idea of a color map is that the atom-attribute will be within a range of values, and that range is associated with a series of colors (e.g. red, blue, green). An atom's specific value (vx = -3.2) can then mapped to the series of colors (e.g. halfway between red and blue), and a specific color is determined via an interpolation procedure. There are many possible options for the color map, enabled by the {amap} keyword. Here are the details. The {lo} and {hi} settings determine the range of values allowed for the atom attribute. If numeric values are used for {lo} and/or {hi}, then values that are lower/higher than that value are set to the value. I.e. the range is static. If {lo} is specified as {min} or {hi} as {max} then the range is dynamic, and the lower and/or upper bound will be calculated each time an image is drawn, based on the set of atoms being visualized. The {style} setting is two letters, such as "ca". The first letter is either "c" for continuous, "d" for discrete, or "s" for sequential. The second letter is either "a" for absolute, or "f" for fractional. A continuous color map is one in which the color changes continuously from value to value within the range. A discrete color map is one in which discrete colors are assigned to sub-ranges of values within the range. A sequential color map is one in which discrete colors are assigned to a sequence of sub-ranges of values covering the entire range. An absolute color map is one in which the values to which colors are assigned are specified explicitly as values within the range. A fractional color map is one in which the values to which colors are assigned are specified as a fractional portion of the range. For example if the range is from -10.0 to 10.0, and the color red is to be assigned to atoms with a value of 5.0, then for an absolute color map the number 5.0 would be used. But for a fractional map, the number 0.75 would be used since 5.0 is 3/4 of the way from -10.0 to 10.0. The {delta} setting must be specified for all styles, but is only used for the sequential style; otherwise the value is ignored. It specifies the bin size to use within the range for assigning consecutive colors to. For example, if the range is from -10.0 to 10.0 and a {delta} of 1.0 is used, then 20 colors will be assigned to the range. The first will be from -10.0 <= color1 < -9.0, then 2nd from -9.0 <= color2 < -8.0, etc. The {N} setting is how many entries follow. The format of the entries depends on whether the color map style is continuous, discrete or sequential. In all cases the {color} setting can be any of the 140 pre-defined colors (see below) or a color name defined by the dump_modify color option. For continuous color maps, each entry has a {value} and a {color}. The {value} is either a number within the range of values or {min} or {max}. The {value} of the first entry must be {min} and the {value} of the last entry must be {max}. Any entries in between must have increasing values. Note that numeric values can be specified either as absolute numbers or as fractions (0.0 to 1.0) of the range, depending on the "a" or "f" in the style setting for the color map. Here is how the entries are used to determine the color of an individual atom, given the value X of its atom attribute. X will fall between 2 of the entry values. The color of the atom is linearly interpolated (in each of the RGB values) between the 2 colors associated with those entries. For example, if X = -5.0 and the 2 surrounding entries are "red" at -10.0 and "blue" at 0.0, then the atom's color will be halfway between "red" and "blue", which happens to be "purple". For discrete color maps, each entry has a {lo} and {hi} value and a {color}. The {lo} and {hi} settings are either numbers within the range of values or {lo} can be {min} or {hi} can be {max}. The {lo} and {hi} settings of the last entry must be {min} and {max}. Other entries can have any {lo} and {hi} values and the sub-ranges of different values can overlap. Note that numeric {lo} and {hi} values can be specified either as absolute numbers or as fractions (0.0 to 1.0) of the range, depending on the "a" or "f" in the style setting for the color map. Here is how the entries are used to determine the color of an individual atom, given the value X of its atom attribute. The entries are scanned from first to last. The first time that {lo} <= X <= {hi}, X is assigned the color associated with that entry. You can think of the last entry as assigning a default color (since it will always be matched by X), and the earlier entries as colors that override the default. Also note that no interpolation of a color RGB is done. All atoms will be drawn with one of the colors in the list of entries. For sequential color maps, each entry has only a {color}. Here is how the entries are used to determine the color of an individual atom, given the value X of its atom attribute. The range is partitioned into N bins of width {binsize}. Thus X will fall in a specific bin from 1 to N, say the Mth bin. If it falls on a boundary between 2 bins, it is considered to be in the higher of the 2 bins. Each bin is assigned a color from the E entries. If E < N, then the colors are repeated. For example if 2 entries with colors red and green are specified, then the odd numbered bins will be red and the even bins green. The color of the atom is the color of its bin. Note that the sequential color map is really a shorthand way of defining a discrete color map without having to specify where all the bin boundaries are. Here is an example of using a sequential color map to color all the atoms in individual molecules with a different color. See the examples/pour/in.pour.2d.molecule input script for an example of how this is used. variable colors string & "red green blue yellow white & purple pink orange lime gray" variable mol atom mol%10 dump 1 all image 250 image.*.jpg v_mol type & zoom 1.6 adiam 1.5 dump_modify 1 pad 5 amap 0 10 sa 1 10 $\{colors\} :pre In this case, 10 colors are defined, and molecule IDs are mapped to one of the colors, even if there are 1000s of molecules. :line The {backcolor} sets the background color of the images. The color name can be any of the 140 pre-defined colors (see below) or a color name defined by the dump_modify color option. :line The {bcolor} keyword can be used with the "dump image"_dump_image.html command, with its {bond} keyword, when its color setting is {type}, to set the color that bonds of each type will be drawn in the image. The specified {type} should be an integer from 1 to Nbondtypes = the number of bond types. A wildcard asterisk can be used in place of or in conjunction with the {type} argument to specify a range of bond types. This takes the form "*" or "*n" or "n*" or "m*n". If N = the number of bond types, then an asterisk with no numeric values means all types from 1 to N. A leading asterisk means all types from 1 to n (inclusive). A trailing asterisk means all types from n to N (inclusive). A middle asterisk means all types from m to n (inclusive). The specified {color} can be a single color which is any of the 140 pre-defined colors (see below) or a color name defined by the dump_modify color option. Or it can be two or more colors separated by a "/" character, e.g. red/green/blue. In the former case, that color is assigned to all the specified bond types. In the latter case, the list of colors are assigned in a round-robin fashion to each of the specified bond types. :line The {bdiam} keyword can be used with the "dump image"_dump_image.html command, with its {bond} keyword, when its diam setting is {type}, to set the diameter that bonds of each type will be drawn in the image. The specified {type} should be an integer from 1 to Nbondtypes. As with the {bcolor} keyword, a wildcard asterisk can be used as part of the {type} argument to specify a range of bond types. The specified {diam} is the size in whatever distance "units"_units.html you are using, e.g. Angstroms. :line The {bitrate} keyword can be used with the "dump movie"_dump_image.html command to define the size of the resulting movie file and its quality via setting how many kbits per second are to be used for the movie file. Higher bitrates require less compression and will result in higher quality movies. The quality is also determined by the compression format and encoder. The default setting is 2000 kbit/s, which will result in average quality with older compression formats. NOTE: Not all movie file formats supported by dump movie allow the bitrate to be set. If not, the setting is silently ignored. :line The {boxcolor} keyword sets the color of the simulation box drawn around the atoms in each image as well as the color of processor sub-domain boundaries. See the "dump image box" command for how to specify that a box be drawn via the {box} keyword, and the sub-domain boundaries via the {subbox} keyword. The color name can be any of the 140 pre-defined colors (see below) or a color name defined by the dump_modify color option. :line The {color} keyword allows definition of a new color name, in addition to the 140-predefined colors (see below), and associates 3 red/green/blue RGB values with that color name. The color name can then be used with any other dump_modify keyword that takes a color name as a value. The RGB values should each be floating point values between 0.0 and 1.0 inclusive. When a color name is converted to RGB values, the user-defined color names are searched first, then the 140 pre-defined color names. This means you can also use the {color} keyword to overwrite one of the pre-defined color names with new RBG values. :line The {framerate} keyword can be used with the "dump movie"_dump_image.html command to define the duration of the resulting movie file. Movie files written by the dump {movie} command have a default frame rate of 24 frames per second and the images generated will be converted at that rate. Thus a sequence of 1000 dump images will result in a movie of about 42 seconds. To make a movie run longer you can either generate images more frequently or lower the frame rate. To speed a movie up, you can do the inverse. Using a frame rate higher than 24 is not recommended, as it will result in simply dropping the rendered images. It is more efficient to dump images less frequently. :line :line [Restrictions:] none [Related commands:] "dump"_dump.html, "dump image"_dump_image.html, "undump"_undump.html [Default:] The option defaults are append = no buffer = yes for dump styles {atom}, {custom}, {loca}, and {xyz} element = "C" for every atom type every = whatever it was set to via the "dump"_dump.html command fileper = # of processors first = no flush = yes format = %d and %g for each integer or floating point value image = no label = ENTRIES nfile = 1 pad = 0 pbc = no precision = 1000 region = none scale = yes sort = off for dump styles {atom}, {custom}, {cfg}, and {local} sort = id for dump styles {dcd}, {xtc}, and {xyz} thresh = none unwrap = no :ul acolor = * red/green/blue/yellow/aqua/cyan adiam = * 1.0 amap = min max cf 0.0 2 min blue max red backcolor = black bcolor = * red/green/blue/yellow/aqua/cyan bdiam = * 0.5 bitrate = 2000 boxcolor = yellow color = 140 color names are pre-defined as listed below framerate = 24 :ul :line These are the standard 109 element names that LAMMPS pre-defines for use with the "dump image"_dump_image.html and dump_modify commands. 1-10 = "H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne" 11-20 = "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca" 21-30 = "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn" 31-40 = "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr" 41-50 = "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn" 51-60 = "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd" 61-70 = "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb" 71-80 = "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg" 81-90 = "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac", "Th" 91-100 = "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm" 101-109 = "Md", "No", "Lr", "Rf", "Db", "Sg", "Bh", "Hs", "Mt" :ul :line These are the 140 colors that LAMMPS pre-defines for use with the "dump image"_dump_image.html and dump_modify commands. Additional colors can be defined with the dump_modify color command. The 3 numbers listed for each name are the RGB (red/green/blue) values. Divide each value by 255 to get the equivalent 0.0 to 1.0 value. aliceblue = 240, 248, 255 | antiquewhite = 250, 235, 215 | aqua = 0, 255, 255 | aquamarine = 127, 255, 212 | azure = 240, 255, 255 | beige = 245, 245, 220 | bisque = 255, 228, 196 | black = 0, 0, 0 | blanchedalmond = 255, 255, 205 | blue = 0, 0, 255 | blueviolet = 138, 43, 226 | brown = 165, 42, 42 | burlywood = 222, 184, 135 | cadetblue = 95, 158, 160 | chartreuse = 127, 255, 0 | chocolate = 210, 105, 30 | coral = 255, 127, 80 | cornflowerblue = 100, 149, 237 | cornsilk = 255, 248, 220 | crimson = 220, 20, 60 | cyan = 0, 255, 255 | darkblue = 0, 0, 139 | darkcyan = 0, 139, 139 | darkgoldenrod = 184, 134, 11 | darkgray = 169, 169, 169 | darkgreen = 0, 100, 0 | darkkhaki = 189, 183, 107 | darkmagenta = 139, 0, 139 | darkolivegreen = 85, 107, 47 | darkorange = 255, 140, 0 | darkorchid = 153, 50, 204 | darkred = 139, 0, 0 | darksalmon = 233, 150, 122 | darkseagreen = 143, 188, 143 | darkslateblue = 72, 61, 139 | darkslategray = 47, 79, 79 | darkturquoise = 0, 206, 209 | darkviolet = 148, 0, 211 | deeppink = 255, 20, 147 | deepskyblue = 0, 191, 255 | dimgray = 105, 105, 105 | dodgerblue = 30, 144, 255 | firebrick = 178, 34, 34 | floralwhite = 255, 250, 240 | forestgreen = 34, 139, 34 | fuchsia = 255, 0, 255 | gainsboro = 220, 220, 220 | ghostwhite = 248, 248, 255 | gold = 255, 215, 0 | goldenrod = 218, 165, 32 | gray = 128, 128, 128 | green = 0, 128, 0 | greenyellow = 173, 255, 47 | honeydew = 240, 255, 240 | hotpink = 255, 105, 180 | indianred = 205, 92, 92 | indigo = 75, 0, 130 | ivory = 255, 240, 240 | khaki = 240, 230, 140 | lavender = 230, 230, 250 | lavenderblush = 255, 240, 245 | lawngreen = 124, 252, 0 | lemonchiffon = 255, 250, 205 | lightblue = 173, 216, 230 | lightcoral = 240, 128, 128 | lightcyan = 224, 255, 255 | lightgoldenrodyellow = 250, 250, 210 | lightgreen = 144, 238, 144 | lightgrey = 211, 211, 211 | lightpink = 255, 182, 193 | lightsalmon = 255, 160, 122 | lightseagreen = 32, 178, 170 | lightskyblue = 135, 206, 250 | lightslategray = 119, 136, 153 | lightsteelblue = 176, 196, 222 | lightyellow = 255, 255, 224 | lime = 0, 255, 0 | limegreen = 50, 205, 50 | linen = 250, 240, 230 | magenta = 255, 0, 255 | maroon = 128, 0, 0 | mediumaquamarine = 102, 205, 170 | mediumblue = 0, 0, 205 | mediumorchid = 186, 85, 211 | mediumpurple = 147, 112, 219 | mediumseagreen = 60, 179, 113 | mediumslateblue = 123, 104, 238 | mediumspringgreen = 0, 250, 154 | mediumturquoise = 72, 209, 204 | mediumvioletred = 199, 21, 133 | midnightblue = 25, 25, 112 | mintcream = 245, 255, 250 | mistyrose = 255, 228, 225 | moccasin = 255, 228, 181 | navajowhite = 255, 222, 173 | navy = 0, 0, 128 | oldlace = 253, 245, 230 | olive = 128, 128, 0 | olivedrab = 107, 142, 35 | orange = 255, 165, 0 | orangered = 255, 69, 0 | orchid = 218, 112, 214 | palegoldenrod = 238, 232, 170 | palegreen = 152, 251, 152 | paleturquoise = 175, 238, 238 | palevioletred = 219, 112, 147 | papayawhip = 255, 239, 213 | peachpuff = 255, 239, 213 | peru = 205, 133, 63 | pink = 255, 192, 203 | plum = 221, 160, 221 | powderblue = 176, 224, 230 | purple = 128, 0, 128 | red = 255, 0, 0 | rosybrown = 188, 143, 143 | royalblue = 65, 105, 225 | saddlebrown = 139, 69, 19 | salmon = 250, 128, 114 | sandybrown = 244, 164, 96 | seagreen = 46, 139, 87 | seashell = 255, 245, 238 | sienna = 160, 82, 45 | silver = 192, 192, 192 | skyblue = 135, 206, 235 | slateblue = 106, 90, 205 | slategray = 112, 128, 144 | snow = 255, 250, 250 | springgreen = 0, 255, 127 | steelblue = 70, 130, 180 | tan = 210, 180, 140 | teal = 0, 128, 128 | thistle = 216, 191, 216 | tomato = 253, 99, 71 | turquoise = 64, 224, 208 | violet = 238, 130, 238 | wheat = 245, 222, 179 | white = 255, 255, 255 | whitesmoke = 245, 245, 245 | yellow = 255, 255, 0 | yellowgreen = 154, 205, 50 :tb(c=5,s=|) diff --git a/src/USER-NETCDF/dump_netcdf.cpp b/src/USER-NETCDF/dump_netcdf.cpp index a9532d107..57404e40d 100644 --- a/src/USER-NETCDF/dump_netcdf.cpp +++ b/src/USER-NETCDF/dump_netcdf.cpp @@ -1,969 +1,974 @@ /* ---------------------------------------------------------------------- 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) #include #include #include #include #include "dump_netcdf.h" #include "atom.h" #include "comm.h" #include "compute.h" #include "domain.h" #include "error.h" #include "fix.h" #include "group.h" #include "input.h" #include "math_const.h" #include "memory.h" #include "modify.h" #include "update.h" #include "universe.h" #include "variable.h" #include "force.h" #include "output.h" #include "thermo.h" using namespace LAMMPS_NS; using namespace MathConst; enum{INT,FLOAT,BIGINT}; // same as in thermo.cpp const char NC_FRAME_STR[] = "frame"; const char NC_SPATIAL_STR[] = "spatial"; const char NC_VOIGT_STR[] = "Voigt"; const char NC_ATOM_STR[] = "atom"; const char NC_CELL_SPATIAL_STR[] = "cell_spatial"; const char NC_CELL_ANGULAR_STR[] = "cell_angular"; const char NC_LABEL_STR[] = "label"; const char NC_TIME_STR[] = "time"; const char NC_CELL_ORIGIN_STR[] = "cell_origin"; const char NC_CELL_LENGTHS_STR[] = "cell_lengths"; const char NC_CELL_ANGLES_STR[] = "cell_angles"; const char NC_UNITS_STR[] = "units"; const char NC_SCALE_FACTOR_STR[] = "scale_factor"; const int THIS_IS_A_FIX = -1; const int THIS_IS_A_COMPUTE = -2; const int THIS_IS_A_VARIABLE = -3; const int THIS_IS_A_BIGINT = -4; /* ---------------------------------------------------------------------- */ #define NCERR(x) ncerr(x, NULL, __LINE__) #define NCERRX(x, descr) ncerr(x, descr, __LINE__) #if !defined(NC_64BIT_DATA) #define NC_64BIT_DATA NC_64BIT_OFFSET #endif /* ---------------------------------------------------------------------- */ DumpNetCDF::DumpNetCDF(LAMMPS *lmp, int narg, char **arg) : DumpCustom(lmp, narg, arg) { // arrays for data rearrangement sort_flag = 1; sortcol = 0; binary = 1; flush_flag = 0; if (multiproc) error->all(FLERR,"Multi-processor writes are not supported."); if (append_flag && multifile) error->all(FLERR,"Cannot append when writing to multiple files."); perat = new nc_perat_t[nfield]; for (int i = 0; i < nfield; i++) { perat[i].dims = 0; } n_perat = 0; for (int iarg = 5; iarg < narg; iarg++) { int i = iarg-5; int idim = 0; int ndims = 1; char mangled[1024]; bool constant = false; strcpy(mangled, arg[iarg]); // name mangling // in the AMBER specification if (!strcmp(mangled, "x") || !strcmp(mangled, "y") || !strcmp(mangled, "z")) { idim = mangled[0] - 'x'; ndims = 3; strcpy(mangled, "coordinates"); } else if (!strcmp(mangled, "vx") || !strcmp(mangled, "vy") || !strcmp(mangled, "vz")) { idim = mangled[1] - 'x'; ndims = 3; strcpy(mangled, "velocities"); } // extensions to the AMBER specification else if (!strcmp(mangled, "type")) { strcpy(mangled, "atom_types"); } else if (!strcmp(mangled, "xs") || !strcmp(mangled, "ys") || !strcmp(mangled, "zs")) { idim = mangled[0] - 'x'; ndims = 3; strcpy(mangled, "scaled_coordinates"); } else if (!strcmp(mangled, "xu") || !strcmp(mangled, "yu") || !strcmp(mangled, "zu")) { idim = mangled[0] - 'x'; ndims = 3; strcpy(mangled, "unwrapped_coordinates"); } else if (!strcmp(mangled, "fx") || !strcmp(mangled, "fy") || !strcmp(mangled, "fz")) { idim = mangled[1] - 'x'; ndims = 3; strcpy(mangled, "forces"); } else if (!strcmp(mangled, "mux") || !strcmp(mangled, "muy") || !strcmp(mangled, "muz")) { idim = mangled[2] - 'x'; ndims = 3; strcpy(mangled, "mu"); } else if (!strncmp(mangled, "c_", 2)) { char *ptr = strchr(mangled, '['); if (ptr) { if (mangled[strlen(mangled)-1] != ']') error->all(FLERR,"Missing ']' in dump command"); *ptr = '\0'; idim = ptr[1] - '1'; ndims = THIS_IS_A_COMPUTE; } } else if (!strncmp(mangled, "f_", 2)) { char *ptr = strchr(mangled, '['); if (ptr) { if (mangled[strlen(mangled)-1] != ']') error->all(FLERR,"Missing ']' in dump command"); *ptr = '\0'; idim = ptr[1] - '1'; ndims = THIS_IS_A_FIX; } } // find mangled name int inc = -1; for (int j = 0; j < n_perat && inc < 0; j++) { if (!strcmp(perat[j].name, mangled)) { inc = j; } } if (inc < 0) { // this has not yet been defined inc = n_perat; perat[inc].dims = ndims; if (ndims < 0) ndims = DUMP_NC_MAX_DIMS; for (int j = 0; j < DUMP_NC_MAX_DIMS; j++) { perat[inc].field[j] = -1; } strcpy(perat[inc].name, mangled); n_perat++; } perat[inc].constant = constant; perat[inc].ndumped = 0; perat[inc].field[idim] = i; } n_buffer = 0; int_buffer = NULL; double_buffer = NULL; double_precision = false; thermo = false; thermovar = NULL; framei = 0; } /* ---------------------------------------------------------------------- */ DumpNetCDF::~DumpNetCDF() { closefile(); delete [] perat; if (thermovar) delete [] thermovar; if (int_buffer) memory->sfree(int_buffer); if (double_buffer) memory->sfree(double_buffer); } /* ---------------------------------------------------------------------- */ void DumpNetCDF::openfile() { char *filecurrent = filename; if (multifile && !singlefile_opened) { char *filestar = filecurrent; filecurrent = new char[strlen(filestar) + 16]; char *ptr = strchr(filestar,'*'); *ptr = '\0'; if (padflag == 0) sprintf(filecurrent,"%s" BIGINT_FORMAT "%s", filestar,update->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,filestar,update->ntimestep,ptr+1); } *ptr = '*'; } if (thermo && !singlefile_opened) { if (thermovar) delete [] thermovar; thermovar = new int[output->thermo->nfield]; } // now the computes and fixes have been initialized, so we can query // for the size of vector quantities for (int i = 0; i < n_perat; i++) { if (perat[i].dims == THIS_IS_A_COMPUTE) { int j = -1; for (int k = 0; k < DUMP_NC_MAX_DIMS; k++) { if (perat[i].field[k] >= 0) { j = field2index[perat[i].field[0]]; } } if (j < 0) error->all(FLERR,"Internal error."); if (!compute[j]->peratom_flag) error->all(FLERR,"compute does not provide per atom data"); perat[i].dims = compute[j]->size_peratom_cols; if (perat[i].dims > DUMP_NC_MAX_DIMS) error->all(FLERR,"perat[i].dims > DUMP_NC_MAX_DIMS"); } else if (perat[i].dims == THIS_IS_A_FIX) { int j = -1; for (int k = 0; k < DUMP_NC_MAX_DIMS; k++) { if (perat[i].field[k] >= 0) { j = field2index[perat[i].field[0]]; } } if (j < 0) error->all(FLERR,"Internal error."); if (!fix[j]->peratom_flag) error->all(FLERR,"fix does not provide per atom data"); perat[i].dims = fix[j]->size_peratom_cols; if (perat[i].dims > DUMP_NC_MAX_DIMS) error->all(FLERR,"perat[i].dims > DUMP_NC_MAX_DIMS"); } } // get total number of atoms ntotalgr = group->count(igroup); if (filewriter) { if (append_flag && !multifile && access(filecurrent, F_OK) != -1) { // Fixme! Perform checks if dimensions and variables conform with // data structure standard. if (singlefile_opened) return; singlefile_opened = 1; NCERRX( nc_open(filecurrent, NC_WRITE, &ncid), filecurrent ); // dimensions NCERRX( nc_inq_dimid(ncid, NC_FRAME_STR, &frame_dim), NC_FRAME_STR ); NCERRX( nc_inq_dimid(ncid, NC_SPATIAL_STR, &spatial_dim), NC_SPATIAL_STR ); NCERRX( nc_inq_dimid(ncid, NC_VOIGT_STR, &Voigt_dim), NC_VOIGT_STR ); NCERRX( nc_inq_dimid(ncid, NC_ATOM_STR, &atom_dim), NC_ATOM_STR ); NCERRX( nc_inq_dimid(ncid, NC_CELL_SPATIAL_STR, &cell_spatial_dim), NC_CELL_SPATIAL_STR ); NCERRX( nc_inq_dimid(ncid, NC_CELL_ANGULAR_STR, &cell_angular_dim), NC_CELL_ANGULAR_STR ); NCERRX( nc_inq_dimid(ncid, NC_LABEL_STR, &label_dim), NC_LABEL_STR ); // default variables NCERRX( nc_inq_varid(ncid, NC_SPATIAL_STR, &spatial_var), NC_SPATIAL_STR ); NCERRX( nc_inq_varid(ncid, NC_CELL_SPATIAL_STR, &cell_spatial_var), NC_CELL_SPATIAL_STR); NCERRX( nc_inq_varid(ncid, NC_CELL_ANGULAR_STR, &cell_angular_var), NC_CELL_ANGULAR_STR); NCERRX( nc_inq_varid(ncid, NC_TIME_STR, &time_var), NC_TIME_STR ); NCERRX( nc_inq_varid(ncid, NC_CELL_ORIGIN_STR, &cell_origin_var), NC_CELL_ORIGIN_STR ); NCERRX( nc_inq_varid(ncid, NC_CELL_LENGTHS_STR, &cell_lengths_var), NC_CELL_LENGTHS_STR); NCERRX( nc_inq_varid(ncid, NC_CELL_ANGLES_STR, &cell_angles_var), NC_CELL_ANGLES_STR); // variables specified in the input file for (int i = 0; i < n_perat; i++) { nc_type xtype; // Type mangling if (vtype[perat[i].field[0]] == INT) { xtype = NC_INT; } else { if (double_precision) xtype = NC_DOUBLE; else xtype = NC_FLOAT; } NCERRX( nc_inq_varid(ncid, perat[i].name, &perat[i].var), perat[i].name ); } // perframe variables if (thermo) { Thermo *th = output->thermo; for (int i = 0; i < th->nfield; i++) { NCERRX( nc_inq_varid(ncid, th->keyword[i], &thermovar[i]), th->keyword[i] ); } } size_t nframes; NCERR( nc_inq_dimlen(ncid, frame_dim, &nframes) ); // framei == -1 means append to file, == -2 means override last frame // Note that in the input file this translates to 'yes', '-1', etc. - if (framei < 0 || (append_flag && framei == 0)) framei = nframes+framei+1; + + if (!append_flag) + error->all(FLERR,"at keyword requires use of 'append yes'"); + + if (framei < 0 || (append_flag && framei == 0)) + framei = nframes+framei+1; if (framei < 1) framei = 1; } else { int dims[NC_MAX_VAR_DIMS]; size_t index[NC_MAX_VAR_DIMS], count[NC_MAX_VAR_DIMS]; double d[1]; if (singlefile_opened) return; singlefile_opened = 1; NCERRX( nc_create(filecurrent, NC_64BIT_DATA, &ncid), filecurrent ); // dimensions NCERRX( nc_def_dim(ncid, NC_FRAME_STR, NC_UNLIMITED, &frame_dim), NC_FRAME_STR ); NCERRX( nc_def_dim(ncid, NC_SPATIAL_STR, 3, &spatial_dim), NC_SPATIAL_STR ); NCERRX( nc_def_dim(ncid, NC_VOIGT_STR, 6, &Voigt_dim), NC_VOIGT_STR ); NCERRX( nc_def_dim(ncid, NC_ATOM_STR, ntotalgr, &atom_dim), NC_ATOM_STR ); NCERRX( nc_def_dim(ncid, NC_CELL_SPATIAL_STR, 3, &cell_spatial_dim), NC_CELL_SPATIAL_STR ); NCERRX( nc_def_dim(ncid, NC_CELL_ANGULAR_STR, 3, &cell_angular_dim), NC_CELL_ANGULAR_STR ); NCERRX( nc_def_dim(ncid, NC_LABEL_STR, 10, &label_dim), NC_LABEL_STR ); // default variables dims[0] = spatial_dim; NCERRX( nc_def_var(ncid, NC_SPATIAL_STR, NC_CHAR, 1, dims, &spatial_var), NC_SPATIAL_STR ); NCERRX( nc_def_var(ncid, NC_CELL_SPATIAL_STR, NC_CHAR, 1, dims, &cell_spatial_var), NC_CELL_SPATIAL_STR ); dims[0] = spatial_dim; dims[1] = label_dim; NCERRX( nc_def_var(ncid, NC_CELL_ANGULAR_STR, NC_CHAR, 2, dims, &cell_angular_var), NC_CELL_ANGULAR_STR ); dims[0] = frame_dim; NCERRX( nc_def_var(ncid, NC_TIME_STR, NC_DOUBLE, 1, dims, &time_var), NC_TIME_STR); dims[0] = frame_dim; dims[1] = cell_spatial_dim; NCERRX( nc_def_var(ncid, NC_CELL_ORIGIN_STR, NC_DOUBLE, 2, dims, &cell_origin_var), NC_CELL_ORIGIN_STR ); NCERRX( nc_def_var(ncid, NC_CELL_LENGTHS_STR, NC_DOUBLE, 2, dims, &cell_lengths_var), NC_CELL_LENGTHS_STR ); dims[0] = frame_dim; dims[1] = cell_angular_dim; NCERRX( nc_def_var(ncid, NC_CELL_ANGLES_STR, NC_DOUBLE, 2, dims, &cell_angles_var), NC_CELL_ANGLES_STR ); // variables specified in the input file dims[0] = frame_dim; dims[1] = atom_dim; dims[2] = spatial_dim; for (int i = 0; i < n_perat; i++) { nc_type xtype; // Type mangling if (vtype[perat[i].field[0]] == INT) { xtype = NC_INT; } else { if (double_precision) xtype = NC_DOUBLE; else xtype = NC_FLOAT; } if (perat[i].constant) { // this quantity will only be written once if (perat[i].dims == 6) { // this is a tensor in Voigt notation dims[2] = Voigt_dim; NCERRX( nc_def_var(ncid, perat[i].name, xtype, 2, dims+1, &perat[i].var), perat[i].name ); } else if (perat[i].dims == 3) { // this is a vector, we need to store x-, y- and z-coordinates dims[2] = spatial_dim; NCERRX( nc_def_var(ncid, perat[i].name, xtype, 2, dims+1, &perat[i].var), perat[i].name ); } else if (perat[i].dims == 1) { NCERRX( nc_def_var(ncid, perat[i].name, xtype, 1, dims+1, &perat[i].var), perat[i].name ); } else { char errstr[1024]; sprintf(errstr, "%i dimensions for '%s'. Not sure how to write " "this to the NetCDF trajectory file.", perat[i].dims, perat[i].name); error->all(FLERR,errstr); } } else { if (perat[i].dims == 6) { // this is a tensor in Voigt notation dims[2] = Voigt_dim; NCERRX( nc_def_var(ncid, perat[i].name, xtype, 3, dims, &perat[i].var), perat[i].name ); } else if (perat[i].dims == 3) { // this is a vector, we need to store x-, y- and z-coordinates dims[2] = spatial_dim; NCERRX( nc_def_var(ncid, perat[i].name, xtype, 3, dims, &perat[i].var), perat[i].name ); } else if (perat[i].dims == 1) { NCERRX( nc_def_var(ncid, perat[i].name, xtype, 2, dims, &perat[i].var), perat[i].name ); } else { char errstr[1024]; sprintf(errstr, "%i dimensions for '%s'. Not sure how to write " "this to the NetCDF trajectory file.", perat[i].dims, perat[i].name); error->all(FLERR,errstr); } } } // perframe variables if (thermo) { Thermo *th = output->thermo; for (int i = 0; i < th->nfield; i++) { if (th->vtype[i] == FLOAT) { NCERRX( nc_def_var(ncid, th->keyword[i], NC_DOUBLE, 1, dims, &thermovar[i]), th->keyword[i] ); } else if (th->vtype[i] == INT) { NCERRX( nc_def_var(ncid, th->keyword[i], NC_INT, 1, dims, &thermovar[i]), th->keyword[i] ); } else if (th->vtype[i] == BIGINT) { NCERRX( nc_def_var(ncid, th->keyword[i], NC_LONG, 1, dims, &thermovar[i]), th->keyword[i] ); } } } // attributes NCERR( nc_put_att_text(ncid, NC_GLOBAL, "Conventions", 5, "AMBER") ); NCERR( nc_put_att_text(ncid, NC_GLOBAL, "ConventionVersion", 3, "1.0") ); NCERR( nc_put_att_text(ncid, NC_GLOBAL, "program", 6, "LAMMPS") ); NCERR( nc_put_att_text(ncid, NC_GLOBAL, "programVersion", strlen(universe->version), universe->version) ); // units if (!strcmp(update->unit_style, "lj")) { NCERR( nc_put_att_text(ncid, time_var, NC_UNITS_STR, 2, "lj") ); NCERR( nc_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, 2, "lj") ); NCERR( nc_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, 2, "lj") ); } else if (!strcmp(update->unit_style, "real")) { NCERR( nc_put_att_text(ncid, time_var, NC_UNITS_STR, 11, "femtosecond") ); NCERR( nc_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, 8, "Angstrom") ); NCERR( nc_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, 8, "Angstrom") ); } else if (!strcmp(update->unit_style, "metal")) { NCERR( nc_put_att_text(ncid, time_var, NC_UNITS_STR, 10, "picosecond") ); NCERR( nc_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, 8, "Angstrom") ); NCERR( nc_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, 8, "Angstrom") ); } else if (!strcmp(update->unit_style, "si")) { NCERR( nc_put_att_text(ncid, time_var, NC_UNITS_STR, 6, "second") ); NCERR( nc_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, 5, "meter") ); NCERR( nc_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, 5, "meter") ); } else if (!strcmp(update->unit_style, "cgs")) { NCERR( nc_put_att_text(ncid, time_var, NC_UNITS_STR, 6, "second") ); NCERR( nc_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, 10, "centimeter") ); NCERR( nc_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, 10, "centimeter") ); } else if (!strcmp(update->unit_style, "electron")) { NCERR( nc_put_att_text(ncid, time_var, NC_UNITS_STR, 11, "femtosecond") ); NCERR( nc_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, 4, "Bohr") ); NCERR( nc_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, 4, "Bohr") ); } else { char errstr[1024]; sprintf(errstr, "Unsupported unit style '%s'", update->unit_style); error->all(FLERR,errstr); } NCERR( nc_put_att_text(ncid, cell_angles_var, NC_UNITS_STR, 6, "degree") ); d[0] = update->dt; NCERR( nc_put_att_double(ncid, time_var, NC_SCALE_FACTOR_STR, NC_DOUBLE, 1, d) ); d[0] = 1.0; NCERR( nc_put_att_double(ncid, cell_origin_var, NC_SCALE_FACTOR_STR, NC_DOUBLE, 1, d) ); d[0] = 1.0; NCERR( nc_put_att_double(ncid, cell_lengths_var, NC_SCALE_FACTOR_STR, NC_DOUBLE, 1, d) ); /* * Finished with definition */ NCERR( nc_enddef(ncid) ); /* * Write label variables */ NCERR( nc_put_var_text(ncid, spatial_var, "xyz") ); NCERR( nc_put_var_text(ncid, cell_spatial_var, "abc") ); index[0] = 0; index[1] = 0; count[0] = 1; count[1] = 5; NCERR( nc_put_vara_text(ncid, cell_angular_var, index, count, "alpha") ); index[0] = 1; count[1] = 4; NCERR( nc_put_vara_text(ncid, cell_angular_var, index, count, "beta") ); index[0] = 2; count[1] = 5; NCERR( nc_put_vara_text(ncid, cell_angular_var, index, count, "gamma") ); framei = 1; } } } /* ---------------------------------------------------------------------- */ void DumpNetCDF::closefile() { if (filewriter && singlefile_opened) { NCERR( nc_close(ncid) ); singlefile_opened = 0; // write to next frame upon next open if (multifile) framei = 1; else { // append next time DumpNetCDF::openfile is called append_flag = 1; framei++; } } } /* ---------------------------------------------------------------------- */ template int nc_put_var1_bigint(int ncid, int varid, const size_t index[], const T* tp) { return nc_put_var1_int(ncid, varid, index, tp); } template <> int nc_put_var1_bigint(int ncid, int varid, const size_t index[], const long* tp) { return nc_put_var1_long(ncid, varid, index, tp); } template <> int nc_put_var1_bigint(int ncid, int varid, const size_t index[], const long long* tp) { return nc_put_var1_longlong(ncid, varid, index, tp); } void DumpNetCDF::write() { // open file openfile(); // need to write per-frame (global) properties here since they may come // from computes. write_header below is only called from the writing // processes, but modify->compute[j]->compute_* must be called from all // processes. size_t start[2]; start[0] = framei-1; start[1] = 0; if (thermo) { Thermo *th = output->thermo; for (int i = 0; i < th->nfield; i++) { th->call_vfunc(i); if (filewriter) { if (th->vtype[i] == FLOAT) { NCERRX( nc_put_var1_double(ncid, thermovar[i], start, &th->dvalue), th->keyword[i] ); } else if (th->vtype[i] == INT) { NCERRX( nc_put_var1_int(ncid, thermovar[i], start, &th->ivalue), th->keyword[i] ); } else if (th->vtype[i] == BIGINT) { NCERRX( nc_put_var1_bigint(ncid, thermovar[i], start, &th->bivalue), th->keyword[i] ); } } } } // call write of superclass Dump::write(); // close file. this ensures data is flushed and mimized data corruption closefile(); } /* ---------------------------------------------------------------------- */ void DumpNetCDF::write_header(bigint n) { size_t start[2]; start[0] = framei-1; start[1] = 0; if (filewriter) { size_t count[2]; double time, cell_origin[3], cell_lengths[3], cell_angles[3]; time = update->ntimestep; if (domain->triclinic == 0) { cell_origin[0] = domain->boxlo[0]; cell_origin[1] = domain->boxlo[1]; cell_origin[2] = domain->boxlo[2]; cell_lengths[0] = domain->xprd; cell_lengths[1] = domain->yprd; cell_lengths[2] = domain->zprd; cell_angles[0] = 90; cell_angles[1] = 90; cell_angles[2] = 90; } else { double cosalpha, cosbeta, cosgamma; double *h = domain->h; cell_origin[0] = domain->boxlo[0]; cell_origin[1] = domain->boxlo[1]; cell_origin[2] = domain->boxlo[2]; cell_lengths[0] = domain->xprd; cell_lengths[1] = sqrt(h[1]*h[1]+h[5]*h[5]); cell_lengths[2] = sqrt(h[2]*h[2]+h[3]*h[3]+h[4]*h[4]); cosalpha = (h[5]*h[4]+h[1]*h[3])/ sqrt((h[1]*h[1]+h[5]*h[5])*(h[2]*h[2]+h[3]*h[3]+h[4]*h[4])); cosbeta = h[4]/sqrt(h[2]*h[2]+h[3]*h[3]+h[4]*h[4]); cosgamma = h[5]/sqrt(h[1]*h[1]+h[5]*h[5]); cell_angles[0] = acos(cosalpha)*180.0/MY_PI; cell_angles[1] = acos(cosbeta)*180.0/MY_PI; cell_angles[2] = acos(cosgamma)*180.0/MY_PI; } // Recent AMBER conventions say that nonperiodic boundaries should have // 'cell_lengths' set to zero. for (int dim = 0; dim < 3; dim++) { if (!domain->periodicity[dim]) cell_lengths[dim] = 0.0; } count[0] = 1; count[1] = 3; NCERR( nc_put_var1_double(ncid, time_var, start, &time) ); NCERR( nc_put_vara_double(ncid, cell_origin_var, start, count, cell_origin) ); NCERR( nc_put_vara_double(ncid, cell_lengths_var, start, count, cell_lengths) ); NCERR( nc_put_vara_double(ncid, cell_angles_var, start, count, cell_angles) ); } ndata = n; blocki = 0; } /* ---------------------------------------------------------------------- write data lines to file in a block-by-block style write head of block (mass & element name) only if has atoms of the type ------------------------------------------------------------------------- */ void DumpNetCDF::write_data(int n, double *mybuf) { size_t start[NC_MAX_VAR_DIMS], count[NC_MAX_VAR_DIMS]; ptrdiff_t stride[NC_MAX_VAR_DIMS]; if (!int_buffer) { n_buffer = n; int_buffer = (int *) memory->smalloc(n*sizeof(int),"dump::int_buffer"); double_buffer = (double *) memory->smalloc(n*sizeof(double),"dump::double_buffer"); } if (n > n_buffer) { n_buffer = n; int_buffer = (int *) memory->srealloc(int_buffer, n*sizeof(int),"dump::int_buffer"); double_buffer = (double *) memory->srealloc(double_buffer, n*sizeof(double),"dump::double_buffer"); } start[0] = framei-1; start[1] = blocki; start[2] = 0; count[0] = 1; count[1] = n; count[2] = 1; stride[0] = 1; stride[1] = 1; stride[2] = 3; for (int i = 0; i < n_perat; i++) { int iaux = perat[i].field[0]; if (vtype[iaux] == INT) { // integers if (perat[i].dims > 1) { for (int idim = 0; idim < perat[i].dims; idim++) { iaux = perat[i].field[idim]; if (iaux >= 0) { for (int j = 0; j < n; j++, iaux+=size_one) { int_buffer[j] = mybuf[iaux]; } start[2] = idim; if (perat[i].constant) { if (perat[i].ndumped < ntotalgr) { NCERR( nc_put_vars_int(ncid, perat[i].var, start+1, count+1, stride+1, int_buffer) ); perat[i].ndumped += n; } } else NCERR( nc_put_vars_int(ncid, perat[i].var, start, count, stride, int_buffer) ); } } } else { for (int j = 0; j < n; j++, iaux+=size_one) { int_buffer[j] = mybuf[iaux]; } if (perat[i].constant) { if (perat[i].ndumped < ntotalgr) { NCERR( nc_put_vara_int(ncid, perat[i].var, start+1, count+1, int_buffer) ); perat[i].ndumped += n; } } else NCERR( nc_put_vara_int(ncid, perat[i].var, start, count, int_buffer) ); } } else { // doubles if (perat[i].dims > 1) { for (int idim = 0; idim < perat[i].dims; idim++) { iaux = perat[i].field[idim]; if (iaux >= 0) { for (int j = 0; j < n; j++, iaux+=size_one) { double_buffer[j] = mybuf[iaux]; } start[2] = idim; if (perat[i].constant) { if (perat[i].ndumped < ntotalgr) { NCERR( nc_put_vars_double(ncid, perat[i].var, start+1, count+1, stride+1, double_buffer) ); perat[i].ndumped += n; } } else NCERR( nc_put_vars_double(ncid, perat[i].var, start, count, stride, double_buffer) ); } } } else { for (int j = 0; j < n; j++, iaux+=size_one) { double_buffer[j] = mybuf[iaux]; } if (perat[i].constant) { if (perat[i].ndumped < ntotalgr) { NCERR( nc_put_vara_double(ncid, perat[i].var, start+1, count+1, double_buffer) ); perat[i].ndumped += n; } } else NCERR( nc_put_vara_double(ncid, perat[i].var, start, count, double_buffer) ); } } } blocki += n; } /* ---------------------------------------------------------------------- */ int DumpNetCDF::modify_param(int narg, char **arg) { int iarg = 0; if (strcmp(arg[iarg],"double") == 0) { iarg++; if (iarg >= narg) error->all(FLERR,"expected 'yes' or 'no' after 'double' keyword."); if (strcmp(arg[iarg],"yes") == 0) { double_precision = true; } else if (strcmp(arg[iarg],"no") == 0) { double_precision = false; } else error->all(FLERR,"expected 'yes' or 'no' after 'double' keyword."); iarg++; return 2; } else if (strcmp(arg[iarg],"at") == 0) { - if (!append_flag) - error->all(FLERR,"expected 'append yes' before 'at' keyword"); iarg++; + if (iarg >= narg) + error->all(FLERR,"expected additional arg after 'at' keyword."); framei = force->inumeric(FLERR,arg[iarg]); - if (framei < 0) framei--; + if (framei < 0) framei--; iarg++; return 2; } else if (strcmp(arg[iarg],"thermo") == 0) { iarg++; if (iarg >= narg) error->all(FLERR,"expected 'yes' or 'no' after 'thermo' keyword."); if (strcmp(arg[iarg],"yes") == 0) { thermo = true; } else if (strcmp(arg[iarg],"no") == 0) { thermo = false; } else error->all(FLERR,"expected 'yes' or 'no' after 'thermo' keyword."); iarg++; return 2; } else return 0; } /* ---------------------------------------------------------------------- */ void DumpNetCDF::ncerr(int err, const char *descr, int line) { if (err != NC_NOERR) { char errstr[1024]; if (descr) { sprintf(errstr, "NetCDF failed with error '%s' (while accessing '%s') " " in line %i of %s.", nc_strerror(err), descr, line, __FILE__); } else { sprintf(errstr, "NetCDF failed with error '%s' in line %i of %s.", nc_strerror(err), line, __FILE__); } error->one(FLERR,errstr); } } #endif /* defined(LMP_HAS_NETCDF) */ diff --git a/src/modify.cpp b/src/modify.cpp index 361079bc1..04137f110 100644 --- a/src/modify.cpp +++ b/src/modify.cpp @@ -1,1597 +1,1596 @@ /* ---------------------------------------------------------------------- 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 "modify.h" #include "style_compute.h" #include "style_fix.h" #include "atom.h" #include "comm.h" #include "fix.h" #include "compute.h" #include "group.h" #include "update.h" #include "domain.h" #include "region.h" #include "input.h" #include "variable.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; using namespace FixConst; #define DELTA 4 #define BIG 1.0e20 #define NEXCEPT 7 // change when add to exceptions in add_fix() /* ---------------------------------------------------------------------- */ Modify::Modify(LAMMPS *lmp) : Pointers(lmp) { nfix = maxfix = 0; n_initial_integrate = n_post_integrate = 0; n_pre_exchange = n_pre_neighbor = 0; n_pre_force = n_pre_reverse = n_post_force = 0; n_final_integrate = n_end_of_step = n_thermo_energy = 0; n_thermo_energy_atom = 0; n_initial_integrate_respa = n_post_integrate_respa = 0; n_pre_force_respa = n_post_force_respa = n_final_integrate_respa = 0; n_min_pre_exchange = n_min_pre_force = n_min_pre_reverse = 0; n_min_post_force = n_min_energy = 0; fix = NULL; fmask = NULL; list_initial_integrate = list_post_integrate = NULL; list_pre_exchange = list_pre_neighbor = NULL; list_pre_force = list_pre_reverse = list_post_force = NULL; list_final_integrate = list_end_of_step = NULL; list_thermo_energy = list_thermo_energy_atom = NULL; list_initial_integrate_respa = list_post_integrate_respa = NULL; list_pre_force_respa = list_post_force_respa = NULL; list_final_integrate_respa = NULL; list_min_pre_exchange = list_min_pre_neighbor = NULL; list_min_pre_force = list_min_pre_reverse = list_min_post_force = NULL; list_min_energy = NULL; end_of_step_every = NULL; list_timeflag = NULL; nfix_restart_global = 0; id_restart_global = style_restart_global = NULL; state_restart_global = NULL; used_restart_global = NULL; nfix_restart_peratom = 0; id_restart_peratom = style_restart_peratom = NULL; index_restart_peratom = used_restart_peratom = NULL; ncompute = maxcompute = 0; compute = NULL; // fill map with fixes listed in style_fix.h fix_map = new FixCreatorMap(); #define FIX_CLASS #define FixStyle(key,Class) \ (*fix_map)[#key] = &fix_creator; #include "style_fix.h" #undef FixStyle #undef FIX_CLASS // fill map with computes listed in style_compute.h compute_map = new ComputeCreatorMap(); #define COMPUTE_CLASS #define ComputeStyle(key,Class) \ (*compute_map)[#key] = &compute_creator; #include "style_compute.h" #undef ComputeStyle #undef COMPUTE_CLASS } /* ---------------------------------------------------------------------- */ Modify::~Modify() { // delete all fixes // do it via delete_fix() so callbacks in Atom are also updated correctly while (nfix) delete_fix(0); memory->sfree(fix); memory->destroy(fmask); // delete all computes for (int i = 0; i < ncompute; i++) delete compute[i]; memory->sfree(compute); delete [] list_initial_integrate; delete [] list_post_integrate; delete [] list_pre_exchange; delete [] list_pre_neighbor; delete [] list_pre_force; delete [] list_pre_reverse; delete [] list_post_force; delete [] list_final_integrate; delete [] list_end_of_step; delete [] list_thermo_energy; delete [] list_thermo_energy_atom; delete [] list_initial_integrate_respa; delete [] list_post_integrate_respa; delete [] list_pre_force_respa; delete [] list_post_force_respa; delete [] list_final_integrate_respa; delete [] list_min_pre_exchange; delete [] list_min_pre_neighbor; delete [] list_min_pre_force; delete [] list_min_pre_reverse; delete [] list_min_post_force; delete [] list_min_energy; delete [] end_of_step_every; delete [] list_timeflag; restart_deallocate(0); delete compute_map; delete fix_map; } /* ---------------------------------------------------------------------- initialize all fixes and computes ------------------------------------------------------------------------- */ void Modify::init() { int i,j; // delete storage of restart info since it is not valid after 1st run restart_deallocate(1); // create lists of fixes to call at each stage of run list_init(INITIAL_INTEGRATE,n_initial_integrate,list_initial_integrate); list_init(POST_INTEGRATE,n_post_integrate,list_post_integrate); list_init(PRE_EXCHANGE,n_pre_exchange,list_pre_exchange); list_init(PRE_NEIGHBOR,n_pre_neighbor,list_pre_neighbor); list_init(PRE_FORCE,n_pre_force,list_pre_force); list_init(PRE_REVERSE,n_pre_reverse,list_pre_reverse); list_init(POST_FORCE,n_post_force,list_post_force); list_init(FINAL_INTEGRATE,n_final_integrate,list_final_integrate); list_init_end_of_step(END_OF_STEP,n_end_of_step,list_end_of_step); list_init_thermo_energy(THERMO_ENERGY,n_thermo_energy,list_thermo_energy); list_init_thermo_energy_atom(n_thermo_energy_atom,list_thermo_energy_atom); list_init(INITIAL_INTEGRATE_RESPA, n_initial_integrate_respa,list_initial_integrate_respa); list_init(POST_INTEGRATE_RESPA, n_post_integrate_respa,list_post_integrate_respa); list_init(POST_FORCE_RESPA, n_post_force_respa,list_post_force_respa); list_init(PRE_FORCE_RESPA, n_pre_force_respa,list_pre_force_respa); list_init(FINAL_INTEGRATE_RESPA, n_final_integrate_respa,list_final_integrate_respa); list_init(MIN_PRE_EXCHANGE,n_min_pre_exchange,list_min_pre_exchange); list_init(MIN_PRE_NEIGHBOR,n_min_pre_neighbor,list_min_pre_neighbor); list_init(MIN_PRE_FORCE,n_min_pre_force,list_min_pre_force); list_init(MIN_PRE_REVERSE,n_min_pre_reverse,list_min_pre_reverse); list_init(MIN_POST_FORCE,n_min_post_force,list_min_post_force); list_init(MIN_ENERGY,n_min_energy,list_min_energy); // init each fix // not sure if now needs to come before compute init // used to b/c temperature computes called fix->dof() in their init, // and fix rigid required its own init before its dof() could be called, // but computes now do their DOF in setup() for (i = 0; i < nfix; i++) fix[i]->init(); // set global flag if any fix has its restart_pbc flag set restart_pbc_any = 0; for (i = 0; i < nfix; i++) if (fix[i]->restart_pbc) restart_pbc_any = 1; // create list of computes that store invocation times list_init_compute(); // init each compute // set invoked_scalar,vector,etc to -1 to force new run to re-compute them // add initial timestep to all computes that store invocation times // since any of them may be invoked by initial thermo // do not clear out invocation times stored within a compute, // b/c some may be holdovers from previous run, like for ave fixes for (i = 0; i < ncompute; i++) { compute[i]->init(); compute[i]->invoked_scalar = -1; compute[i]->invoked_vector = -1; compute[i]->invoked_array = -1; compute[i]->invoked_peratom = -1; compute[i]->invoked_local = -1; } addstep_compute_all(update->ntimestep); // error if any fix or compute is using a dynamic group when not allowed for (i = 0; i < nfix; i++) if (!fix[i]->dynamic_group_allow && group->dynamic[fix[i]->igroup]) { char str[128]; sprintf(str,"Fix %s does not allow use of dynamic group",fix[i]->id); error->all(FLERR,str); } for (i = 0; i < ncompute; i++) if (!compute[i]->dynamic_group_allow && group->dynamic[compute[i]->igroup]) { char str[128]; sprintf(str,"Compute %s does not allow use of dynamic group",fix[i]->id); error->all(FLERR,str); } // warn if any particle is time integrated more than once int nlocal = atom->nlocal; int *mask = atom->mask; int *flag = new int[nlocal]; for (i = 0; i < nlocal; i++) flag[i] = 0; int groupbit; for (i = 0; i < nfix; i++) { if (fix[i]->time_integrate == 0) continue; groupbit = fix[i]->groupbit; for (j = 0; j < nlocal; j++) if (mask[j] & groupbit) flag[j]++; } int check = 0; for (i = 0; i < nlocal; i++) if (flag[i] > 1) check = 1; delete [] flag; int checkall; MPI_Allreduce(&check,&checkall,1,MPI_INT,MPI_SUM,world); if (comm->me == 0 && checkall) error->warning(FLERR, "One or more atoms are time integrated more than once"); } /* ---------------------------------------------------------------------- setup for run, calls setup() of all fixes and computes called from Verlet, RESPA, Min ------------------------------------------------------------------------- */ void Modify::setup(int vflag) { // compute setup needs to come before fix setup // b/c NH fixes need DOF of temperature computes // fix group setup() is special case since populates a dynamic group // needs to be done before temperature compute setup for (int i = 0; i < nfix; i++) if (strcmp(fix[i]->style,"GROUP") == 0) fix[i]->setup(vflag); for (int i = 0; i < ncompute; i++) compute[i]->setup(); if (update->whichflag == 1) for (int i = 0; i < nfix; i++) fix[i]->setup(vflag); else if (update->whichflag == 2) for (int i = 0; i < nfix; i++) fix[i]->min_setup(vflag); } /* ---------------------------------------------------------------------- setup pre_exchange call, only for fixes that define pre_exchange called from Verlet, RESPA, Min, and WriteRestart with whichflag = 0 ------------------------------------------------------------------------- */ void Modify::setup_pre_exchange() { if (update->whichflag <= 1) for (int i = 0; i < n_pre_exchange; i++) fix[list_pre_exchange[i]]->setup_pre_exchange(); else if (update->whichflag == 2) for (int i = 0; i < n_min_pre_exchange; i++) fix[list_min_pre_exchange[i]]->setup_pre_exchange(); } /* ---------------------------------------------------------------------- setup pre_neighbor call, only for fixes that define pre_neighbor called from Verlet, RESPA ------------------------------------------------------------------------- */ void Modify::setup_pre_neighbor() { if (update->whichflag == 1) for (int i = 0; i < n_pre_neighbor; i++) fix[list_pre_neighbor[i]]->setup_pre_neighbor(); else if (update->whichflag == 2) for (int i = 0; i < n_min_pre_neighbor; i++) fix[list_min_pre_neighbor[i]]->setup_pre_neighbor(); } /* ---------------------------------------------------------------------- setup pre_force call, only for fixes that define pre_force called from Verlet, RESPA, Min ------------------------------------------------------------------------- */ void Modify::setup_pre_force(int vflag) { if (update->whichflag == 1) for (int i = 0; i < n_pre_force; i++) fix[list_pre_force[i]]->setup_pre_force(vflag); else if (update->whichflag == 2) for (int i = 0; i < n_min_pre_force; i++) fix[list_min_pre_force[i]]->setup_pre_force(vflag); } /* ---------------------------------------------------------------------- setup pre_reverse call, only for fixes that define pre_reverse called from Verlet, RESPA, Min ------------------------------------------------------------------------- */ void Modify::setup_pre_reverse(int eflag, int vflag) { if (update->whichflag == 1) for (int i = 0; i < n_pre_reverse; i++) fix[list_pre_reverse[i]]->setup_pre_reverse(eflag,vflag); else if (update->whichflag == 2) for (int i = 0; i < n_min_pre_reverse; i++) fix[list_min_pre_reverse[i]]->setup_pre_reverse(eflag,vflag); } /* ---------------------------------------------------------------------- 1st half of integrate call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::initial_integrate(int vflag) { for (int i = 0; i < n_initial_integrate; i++) fix[list_initial_integrate[i]]->initial_integrate(vflag); } /* ---------------------------------------------------------------------- post_integrate call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::post_integrate() { for (int i = 0; i < n_post_integrate; i++) fix[list_post_integrate[i]]->post_integrate(); } /* ---------------------------------------------------------------------- pre_exchange call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::pre_exchange() { for (int i = 0; i < n_pre_exchange; i++) fix[list_pre_exchange[i]]->pre_exchange(); } /* ---------------------------------------------------------------------- pre_neighbor call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::pre_neighbor() { for (int i = 0; i < n_pre_neighbor; i++) fix[list_pre_neighbor[i]]->pre_neighbor(); } /* ---------------------------------------------------------------------- pre_force call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::pre_force(int vflag) { for (int i = 0; i < n_pre_force; i++) fix[list_pre_force[i]]->pre_force(vflag); } /* ---------------------------------------------------------------------- pre_reverse call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::pre_reverse(int eflag, int vflag) { for (int i = 0; i < n_pre_reverse; i++) fix[list_pre_reverse[i]]->pre_reverse(eflag,vflag); } /* ---------------------------------------------------------------------- post_force call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::post_force(int vflag) { for (int i = 0; i < n_post_force; i++) fix[list_post_force[i]]->post_force(vflag); } /* ---------------------------------------------------------------------- 2nd half of integrate call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::final_integrate() { for (int i = 0; i < n_final_integrate; i++) fix[list_final_integrate[i]]->final_integrate(); } /* ---------------------------------------------------------------------- end-of-timestep call, only for relevant fixes only call fix->end_of_step() on timesteps that are multiples of nevery ------------------------------------------------------------------------- */ void Modify::end_of_step() { for (int i = 0; i < n_end_of_step; i++) if (update->ntimestep % end_of_step_every[i] == 0) fix[list_end_of_step[i]]->end_of_step(); } /* ---------------------------------------------------------------------- thermo energy call, only for relevant fixes called by Thermo class compute_scalar() is fix call to return energy ------------------------------------------------------------------------- */ double Modify::thermo_energy() { double energy = 0.0; for (int i = 0; i < n_thermo_energy; i++) energy += fix[list_thermo_energy[i]]->compute_scalar(); return energy; } /* ---------------------------------------------------------------------- per-atom thermo energy call, only for relevant fixes called by compute pe/atom ------------------------------------------------------------------------- */ void Modify::thermo_energy_atom(int nlocal, double *energy) { int i,j; double *eatom; for (i = 0; i < n_thermo_energy_atom; i++) { eatom = fix[list_thermo_energy_atom[i]]->eatom; if (!eatom) continue; for (j = 0; j < nlocal; j++) energy[j] += eatom[j]; } } /* ---------------------------------------------------------------------- post_run call ------------------------------------------------------------------------- */ void Modify::post_run() { for (int i = 0; i < nfix; i++) fix[i]->post_run(); } /* ---------------------------------------------------------------------- create_attribute call invoked when an atom is added to system during a run necessary so that fixes and computes that store per-atom state can initialize that state for the new atom N computes can store per-atom state via a fix like fix STORE compute has the create_attribute flag, not fix STORE ------------------------------------------------------------------------- */ void Modify::create_attribute(int n) { for (int i = 0; i < nfix; i++) if (fix[i]->create_attribute) fix[i]->set_arrays(n); for (int i = 0; i < ncompute; i++) if (compute[i]->create_attribute) compute[i]->set_arrays(n); input->variable->set_arrays(n); } /* ---------------------------------------------------------------------- setup rRESPA pre_force call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::setup_pre_force_respa(int vflag, int ilevel) { for (int i = 0; i < n_pre_force_respa; i++) fix[list_pre_force_respa[i]]->setup_pre_force_respa(vflag,ilevel); } /* ---------------------------------------------------------------------- 1st half of rRESPA integrate call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::initial_integrate_respa(int vflag, int ilevel, int iloop) { for (int i = 0; i < n_initial_integrate_respa; i++) fix[list_initial_integrate_respa[i]]-> initial_integrate_respa(vflag,ilevel,iloop); } /* ---------------------------------------------------------------------- rRESPA post_integrate call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::post_integrate_respa(int ilevel, int iloop) { for (int i = 0; i < n_post_integrate_respa; i++) fix[list_post_integrate_respa[i]]->post_integrate_respa(ilevel,iloop); } /* ---------------------------------------------------------------------- rRESPA pre_force call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::pre_force_respa(int vflag, int ilevel, int iloop) { for (int i = 0; i < n_pre_force_respa; i++) fix[list_pre_force_respa[i]]->pre_force_respa(vflag,ilevel,iloop); } /* ---------------------------------------------------------------------- rRESPA post_force call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::post_force_respa(int vflag, int ilevel, int iloop) { for (int i = 0; i < n_post_force_respa; i++) fix[list_post_force_respa[i]]->post_force_respa(vflag,ilevel,iloop); } /* ---------------------------------------------------------------------- 2nd half of rRESPA integrate call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::final_integrate_respa(int ilevel, int iloop) { for (int i = 0; i < n_final_integrate_respa; i++) fix[list_final_integrate_respa[i]]->final_integrate_respa(ilevel,iloop); } /* ---------------------------------------------------------------------- minimizer pre-exchange call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::min_pre_exchange() { for (int i = 0; i < n_min_pre_exchange; i++) fix[list_min_pre_exchange[i]]->min_pre_exchange(); } /* ---------------------------------------------------------------------- minimizer pre-neighbor call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::min_pre_neighbor() { for (int i = 0; i < n_min_pre_neighbor; i++) fix[list_min_pre_neighbor[i]]->min_pre_neighbor(); } /* ---------------------------------------------------------------------- minimizer pre-force call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::min_pre_force(int vflag) { for (int i = 0; i < n_min_pre_force; i++) fix[list_min_pre_force[i]]->min_pre_force(vflag); } /* ---------------------------------------------------------------------- minimizer pre-reverse call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::min_pre_reverse(int eflag, int vflag) { for (int i = 0; i < n_min_pre_reverse; i++) fix[list_min_pre_reverse[i]]->min_pre_reverse(eflag,vflag); } /* ---------------------------------------------------------------------- minimizer force adjustment call, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::min_post_force(int vflag) { for (int i = 0; i < n_min_post_force; i++) fix[list_min_post_force[i]]->min_post_force(vflag); } /* ---------------------------------------------------------------------- minimizer energy/force evaluation, only for relevant fixes return energy and forces on extra degrees of freedom ------------------------------------------------------------------------- */ double Modify::min_energy(double *fextra) { int ifix,index; index = 0; double eng = 0.0; for (int i = 0; i < n_min_energy; i++) { ifix = list_min_energy[i]; eng += fix[ifix]->min_energy(&fextra[index]); index += fix[ifix]->min_dof(); } return eng; } /* ---------------------------------------------------------------------- store current state of extra minimizer dof, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::min_store() { for (int i = 0; i < n_min_energy; i++) fix[list_min_energy[i]]->min_store(); } /* ---------------------------------------------------------------------- manage state of extra minimizer dof on a stack, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::min_clearstore() { for (int i = 0; i < n_min_energy; i++) fix[list_min_energy[i]]->min_clearstore(); } void Modify::min_pushstore() { for (int i = 0; i < n_min_energy; i++) fix[list_min_energy[i]]->min_pushstore(); } void Modify::min_popstore() { for (int i = 0; i < n_min_energy; i++) fix[list_min_energy[i]]->min_popstore(); } /* ---------------------------------------------------------------------- displace extra minimizer dof along vector hextra, only for relevant fixes ------------------------------------------------------------------------- */ void Modify::min_step(double alpha, double *hextra) { int ifix,index; index = 0; for (int i = 0; i < n_min_energy; i++) { ifix = list_min_energy[i]; fix[ifix]->min_step(alpha,&hextra[index]); index += fix[ifix]->min_dof(); } } /* ---------------------------------------------------------------------- compute max allowed step size along vector hextra, only for relevant fixes ------------------------------------------------------------------------- */ double Modify::max_alpha(double *hextra) { int ifix,index; double alpha = BIG; index = 0; for (int i = 0; i < n_min_energy; i++) { ifix = list_min_energy[i]; double alpha_one = fix[ifix]->max_alpha(&hextra[index]); alpha = MIN(alpha,alpha_one); index += fix[ifix]->min_dof(); } return alpha; } /* ---------------------------------------------------------------------- extract extra minimizer dof, only for relevant fixes ------------------------------------------------------------------------- */ int Modify::min_dof() { int ndof = 0; for (int i = 0; i < n_min_energy; i++) ndof += fix[list_min_energy[i]]->min_dof(); return ndof; } /* ---------------------------------------------------------------------- reset minimizer reference state of fix, only for relevant fixes ------------------------------------------------------------------------- */ int Modify::min_reset_ref() { int itmp,itmpall; itmpall = 0; for (int i = 0; i < n_min_energy; i++) { itmp = fix[list_min_energy[i]]->min_reset_ref(); if (itmp) itmpall = 1; } return itmpall; } /* ---------------------------------------------------------------------- add a new fix or replace one with same ID ------------------------------------------------------------------------- */ void Modify::add_fix(int narg, char **arg, int trysuffix) { if (narg < 3) error->all(FLERR,"Illegal fix command"); // cannot define fix before box exists unless style is in exception list // don't like this way of checking for exceptions by adding fixes to list, // but can't think of better way // too late if instantiate fix, then check flag set in fix constructor, // since some fixes access domain settings in their constructor // MUST change NEXCEPT above when add new fix to this list const char *exceptions[NEXCEPT] = {"GPU","OMP","INTEL","property/atom","cmap","cmap3","rx"}; if (domain->box_exist == 0) { int m; for (m = 0; m < NEXCEPT; m++) if (strcmp(arg[2],exceptions[m]) == 0) break; if (m == NEXCEPT) error->all(FLERR,"Fix command before simulation box is defined"); } // check group ID int igroup = group->find(arg[1]); if (igroup == -1) error->all(FLERR,"Could not find fix group ID"); // if fix ID exists: // set newflag = 0 so create new fix in same location in fix list // error if new style does not match old style // since can't replace it (all when-to-invoke ptrs would be invalid) // warn if new group != old group // delete old fix, but do not call update_callback(), // since will replace this fix and thus other fix locs will not change // set ptr to NULL in case new fix scans list of fixes, // e.g. scan will occur in add_callback() if called by new fix // if fix ID does not exist: // set newflag = 1 so create new fix // extend fix and fmask lists as necessary int ifix,newflag; for (ifix = 0; ifix < nfix; ifix++) if (strcmp(arg[0],fix[ifix]->id) == 0) break; if (ifix < nfix) { newflag = 0; int match = 0; if (strcmp(arg[2],fix[ifix]->style) == 0) match = 1; if (!match && trysuffix && lmp->suffix_enable) { char estyle[256]; if (lmp->suffix) { sprintf(estyle,"%s/%s",arg[2],lmp->suffix); if (strcmp(estyle,fix[ifix]->style) == 0) match = 1; } if (lmp->suffix2) { sprintf(estyle,"%s/%s",arg[2],lmp->suffix2); if (strcmp(estyle,fix[ifix]->style) == 0) match = 1; } } if (!match) error->all(FLERR, "Replacing a fix, but new style != old style"); if (fix[ifix]->igroup != igroup && comm->me == 0) error->warning(FLERR,"Replacing a fix, but new group != old group"); delete fix[ifix]; fix[ifix] = NULL; } else { newflag = 1; if (nfix == maxfix) { maxfix += DELTA; fix = (Fix **) memory->srealloc(fix,maxfix*sizeof(Fix *),"modify:fix"); memory->grow(fmask,maxfix,"modify:fmask"); } } // create the Fix // try first with suffix appended fix[ifix] = NULL; if (trysuffix && lmp->suffix_enable) { if (lmp->suffix) { int n = strlen(arg[2])+strlen(lmp->suffix)+2; char *estyle = new char[n]; sprintf(estyle,"%s/%s",arg[2],lmp->suffix); if (fix_map->find(estyle) != fix_map->end()) { FixCreator fix_creator = (*fix_map)[estyle]; fix[ifix] = fix_creator(lmp,narg,arg); delete[] fix[ifix]->style; fix[ifix]->style = estyle; } else delete[] estyle; } if (fix[ifix] == NULL && lmp->suffix2) { int n = strlen(arg[2])+strlen(lmp->suffix2)+2; char *estyle = new char[n]; sprintf(estyle,"%s/%s",arg[2],lmp->suffix2); if (fix_map->find(estyle) != fix_map->end()) { FixCreator fix_creator = (*fix_map)[estyle]; fix[ifix] = fix_creator(lmp,narg,arg); delete[] fix[ifix]->style; fix[ifix]->style = estyle; } else delete[] estyle; } } if (fix[ifix] == NULL && fix_map->find(arg[2]) != fix_map->end()) { FixCreator fix_creator = (*fix_map)[arg[2]]; fix[ifix] = fix_creator(lmp,narg,arg); } if (fix[ifix] == NULL) { char str[128]; sprintf(str,"Unknown fix style %s",arg[2]); error->all(FLERR,str); } // check if Fix is in restart_global list // if yes, pass state info to the Fix so it can reset itself for (int i = 0; i < nfix_restart_global; i++) if (strcmp(id_restart_global[i],fix[ifix]->id) == 0 && strcmp(style_restart_global[i],fix[ifix]->style) == 0) { fix[ifix]->restart(state_restart_global[i]); used_restart_global[i] = 1; if (comm->me == 0) { if (screen) fprintf(screen,"Resetting global fix info from restart file:\n"); if (logfile) fprintf(logfile,"Resetting global fix info from restart file:\n"); if (screen) fprintf(screen," fix style: %s, fix ID: %s\n", fix[ifix]->style,fix[ifix]->id); if (logfile) fprintf(logfile," fix style: %s, fix ID: %s\n", fix[ifix]->style,fix[ifix]->id); } } // check if Fix is in restart_peratom list // if yes, loop over atoms so they can extract info from atom->extra array for (int i = 0; i < nfix_restart_peratom; i++) if (strcmp(id_restart_peratom[i],fix[ifix]->id) == 0 && strcmp(style_restart_peratom[i],fix[ifix]->style) == 0) { used_restart_peratom[i] = 1; for (int j = 0; j < atom->nlocal; j++) fix[ifix]->unpack_restart(j,index_restart_peratom[i]); fix[ifix]->restart_reset = 1; if (comm->me == 0) { if (screen) fprintf(screen,"Resetting peratom fix info from restart file:\n"); if (logfile) fprintf(logfile,"Resetting peratom fix info from restart file:\n"); if (screen) fprintf(screen," fix style: %s, fix ID: %s\n", fix[ifix]->style,fix[ifix]->id); if (logfile) fprintf(logfile," fix style: %s, fix ID: %s\n", fix[ifix]->style,fix[ifix]->id); } } // increment nfix (if new) // set fix mask values // post_constructor() allows new fix to create other fixes // nfix increment comes first so that recursive call to add_fix within // post_constructor() will see updated nfix if (newflag) nfix++; fmask[ifix] = fix[ifix]->setmask(); fix[ifix]->post_constructor(); } /* ---------------------------------------------------------------------- one instance per fix in style_fix.h ------------------------------------------------------------------------- */ template Fix *Modify::fix_creator(LAMMPS *lmp, int narg, char **arg) { return new T(lmp,narg,arg); } /* ---------------------------------------------------------------------- modify a Fix's parameters ------------------------------------------------------------------------- */ void Modify::modify_fix(int narg, char **arg) { if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); // lookup Fix ID int ifix; for (ifix = 0; ifix < nfix; ifix++) if (strcmp(arg[0],fix[ifix]->id) == 0) break; if (ifix == nfix) error->all(FLERR,"Could not find fix_modify ID"); fix[ifix]->modify_params(narg-1,&arg[1]); } /* ---------------------------------------------------------------------- delete a Fix from list of Fixes Atom class must update indices in its list of callbacks to fixes ------------------------------------------------------------------------- */ void Modify::delete_fix(const char *id) { int ifix = find_fix(id); if (ifix < 0) error->all(FLERR,"Could not find fix ID to delete"); delete_fix(ifix); } void Modify::delete_fix(int ifix) { - if(fix[ifix]) - delete fix[ifix]; + if (fix[ifix]) delete fix[ifix]; atom->update_callback(ifix); // move other Fixes and fmask down in list one slot for (int i = ifix+1; i < nfix; i++) fix[i-1] = fix[i]; for (int i = ifix+1; i < nfix; i++) fmask[i-1] = fmask[i]; nfix--; } /* ---------------------------------------------------------------------- find a fix by ID return index of fix or -1 if not found ------------------------------------------------------------------------- */ int Modify::find_fix(const char *id) { if (id == NULL) return -1; int ifix; for (ifix = 0; ifix < nfix; ifix++) if (strcmp(id,fix[ifix]->id) == 0) break; if (ifix == nfix) return -1; return ifix; } /* ---------------------------------------------------------------------- find a fix by style return index of fix or -1 if not found ------------------------------------------------------------------------- */ int Modify::find_fix_by_style(const char *style) { int ifix; for (ifix = 0; ifix < nfix; ifix++) if (strcmp(style,fix[ifix]->style) == 0) break; if (ifix == nfix) return -1; return ifix; } /* ---------------------------------------------------------------------- check for fix associated with package name in compiled list return 1 if found else 0 used to determine whether LAMMPS was built with GPU, USER-INTEL, USER-OMP packages, which have their own fixes ------------------------------------------------------------------------- */ int Modify::check_package(const char *package_fix_name) { if (fix_map->find(package_fix_name) == fix_map->end()) return 0; return 1; } /* ---------------------------------------------------------------------- check if the group indicated by groupbit overlaps with any currently existing rigid fixes. return 1 in this case otherwise 0 ------------------------------------------------------------------------- */ int Modify::check_rigid_group_overlap(int groupbit) { const int * const mask = atom->mask; const int nlocal = atom->nlocal; int dim; int n = 0; for (int ifix = 0; ifix < nfix; ifix++) { if (strncmp("rigid",fix[ifix]->style,5) == 0) { const int * const body = (const int *)fix[ifix]->extract("body",dim); if ((body == NULL) || (dim != 1)) break; for (int i=0; (i < nlocal) && (n == 0); ++i) if ((mask[i] & groupbit) && (body[i] >= 0)) ++n; } } int n_all = 0; MPI_Allreduce(&n,&n_all,1,MPI_INT,MPI_SUM,world); if (n_all > 0) return 1; return 0; } /* ---------------------------------------------------------------------- check if the atoms in the group indicated by groupbit _and_ region indicated by regionid overlap with any currently existing rigid fixes. return 1 in this case, otherwise 0 ------------------------------------------------------------------------- */ int Modify::check_rigid_region_overlap(int groupbit, Region *reg) { const int * const mask = atom->mask; const double * const * const x = atom->x; const int nlocal = atom->nlocal; int dim; int n = 0; reg->prematch(); for (int ifix = 0; ifix < nfix; ifix++) { if (strncmp("rigid",fix[ifix]->style,5) == 0) { const int * const body = (const int *)fix[ifix]->extract("body",dim); if ((body == NULL) || (dim != 1)) break; for (int i=0; (i < nlocal) && (n == 0); ++i) if ((mask[i] & groupbit) && (body[i] >= 0) && reg->match(x[i][0],x[i][1],x[i][2])) ++n; } } int n_all = 0; MPI_Allreduce(&n,&n_all,1,MPI_INT,MPI_SUM,world); if (n_all > 0) return 1; return 0; } /* ---------------------------------------------------------------------- check if the atoms in the selection list (length atom->nlocal, content: 1 if atom is contained, 0 if not) overlap with currently existing rigid fixes. return 1 in this case otherwise 0 ------------------------------------------------------------------------- */ int Modify::check_rigid_list_overlap(int *select) { const int nlocal = atom->nlocal; int dim; int n = 0; for (int ifix = 0; ifix < nfix; ifix++) { if (strncmp("rigid",fix[ifix]->style,5) == 0) { const int * const body = (const int *)fix[ifix]->extract("body",dim); if ((body == NULL) || (dim != 1)) break; for (int i=0; (i < nlocal) && (n == 0); ++i) if ((body[i] >= 0) && select[i]) ++n; } } int n_all = 0; MPI_Allreduce(&n,&n_all,1,MPI_INT,MPI_SUM,world); if (n_all > 0) return 1; return 0; } /* ---------------------------------------------------------------------- add a new compute ------------------------------------------------------------------------- */ void Modify::add_compute(int narg, char **arg, int trysuffix) { if (narg < 3) error->all(FLERR,"Illegal compute command"); // error check for (int icompute = 0; icompute < ncompute; icompute++) if (strcmp(arg[0],compute[icompute]->id) == 0) error->all(FLERR,"Reuse of compute ID"); // extend Compute list if necessary if (ncompute == maxcompute) { maxcompute += DELTA; compute = (Compute **) memory->srealloc(compute,maxcompute*sizeof(Compute *),"modify:compute"); } // create the Compute // try first with suffix appended compute[ncompute] = NULL; if (trysuffix && lmp->suffix_enable) { if (lmp->suffix) { int n = strlen(arg[2])+strlen(lmp->suffix)+2; char *estyle = new char[n]; sprintf(estyle,"%s/%s",arg[2],lmp->suffix); if (compute_map->find(estyle) != compute_map->end()) { ComputeCreator compute_creator = (*compute_map)[estyle]; compute[ncompute] = compute_creator(lmp,narg,arg); delete[] compute[ncompute]->style; compute[ncompute]->style = estyle; } else delete[] estyle; } if (compute[ncompute] == NULL && lmp->suffix2) { int n = strlen(arg[2])+strlen(lmp->suffix2)+2; char *estyle = new char[n]; sprintf(estyle,"%s/%s",arg[2],lmp->suffix2); if (compute_map->find(estyle) != compute_map->end()) { ComputeCreator compute_creator = (*compute_map)[estyle]; compute[ncompute] = compute_creator(lmp,narg,arg); delete[] compute[ncompute]->style; compute[ncompute]->style = estyle; } else delete[] estyle; } } if (compute[ncompute] == NULL && compute_map->find(arg[2]) != compute_map->end()) { ComputeCreator compute_creator = (*compute_map)[arg[2]]; compute[ncompute] = compute_creator(lmp,narg,arg); } if (compute[ncompute] == NULL) { char str[128]; sprintf(str,"Unknown compute style %s",arg[2]); error->all(FLERR,str); } ncompute++; } /* ---------------------------------------------------------------------- one instance per compute in style_compute.h ------------------------------------------------------------------------- */ template Compute *Modify::compute_creator(LAMMPS *lmp, int narg, char **arg) { return new T(lmp,narg,arg); } /* ---------------------------------------------------------------------- modify a Compute's parameters ------------------------------------------------------------------------- */ void Modify::modify_compute(int narg, char **arg) { if (narg < 2) error->all(FLERR,"Illegal compute_modify command"); // lookup Compute ID int icompute; for (icompute = 0; icompute < ncompute; icompute++) if (strcmp(arg[0],compute[icompute]->id) == 0) break; if (icompute == ncompute) error->all(FLERR,"Could not find compute_modify ID"); compute[icompute]->modify_params(narg-1,&arg[1]); } /* ---------------------------------------------------------------------- delete a Compute from list of Computes ------------------------------------------------------------------------- */ void Modify::delete_compute(const char *id) { int icompute = find_compute(id); if (icompute < 0) error->all(FLERR,"Could not find compute ID to delete"); delete compute[icompute]; // move other Computes down in list one slot for (int i = icompute+1; i < ncompute; i++) compute[i-1] = compute[i]; ncompute--; } /* ---------------------------------------------------------------------- find a compute by ID return index of compute or -1 if not found ------------------------------------------------------------------------- */ int Modify::find_compute(const char *id) { if(id==NULL) return -1; int icompute; for (icompute = 0; icompute < ncompute; icompute++) if (strcmp(id,compute[icompute]->id) == 0) break; if (icompute == ncompute) return -1; return icompute; } /* ---------------------------------------------------------------------- clear invoked flag of all computes called everywhere that computes are used, before computes are invoked invoked flag used to avoid re-invoking same compute multiple times and to flag computes that store invocation times as having been invoked ------------------------------------------------------------------------- */ void Modify::clearstep_compute() { for (int icompute = 0; icompute < ncompute; icompute++) compute[icompute]->invoked_flag = 0; } /* ---------------------------------------------------------------------- loop over computes that store invocation times if its invoked flag set on this timestep, schedule next invocation called everywhere that computes are used, after computes are invoked ------------------------------------------------------------------------- */ void Modify::addstep_compute(bigint newstep) { for (int icompute = 0; icompute < n_timeflag; icompute++) if (compute[list_timeflag[icompute]]->invoked_flag) compute[list_timeflag[icompute]]->addstep(newstep); } /* ---------------------------------------------------------------------- loop over all computes schedule next invocation for those that store invocation times called when not sure what computes will be needed on newstep do not loop only over n_timeflag, since may not be set yet ------------------------------------------------------------------------- */ void Modify::addstep_compute_all(bigint newstep) { for (int icompute = 0; icompute < ncompute; icompute++) if (compute[icompute]->timeflag) compute[icompute]->addstep(newstep); } /* ---------------------------------------------------------------------- write to restart file for all Fixes with restart info (1) fixes that have global state (2) fixes that store per-atom quantities ------------------------------------------------------------------------- */ void Modify::write_restart(FILE *fp) { int me = comm->me; int count = 0; for (int i = 0; i < nfix; i++) if (fix[i]->restart_global) count++; if (me == 0) fwrite(&count,sizeof(int),1,fp); int n; for (int i = 0; i < nfix; i++) if (fix[i]->restart_global) { if (me == 0) { n = strlen(fix[i]->id) + 1; fwrite(&n,sizeof(int),1,fp); fwrite(fix[i]->id,sizeof(char),n,fp); n = strlen(fix[i]->style) + 1; fwrite(&n,sizeof(int),1,fp); fwrite(fix[i]->style,sizeof(char),n,fp); } fix[i]->write_restart(fp); } count = 0; for (int i = 0; i < nfix; i++) if (fix[i]->restart_peratom) count++; if (me == 0) fwrite(&count,sizeof(int),1,fp); for (int i = 0; i < nfix; i++) if (fix[i]->restart_peratom) { int maxsize_restart = fix[i]->maxsize_restart(); if (me == 0) { n = strlen(fix[i]->id) + 1; fwrite(&n,sizeof(int),1,fp); fwrite(fix[i]->id,sizeof(char),n,fp); n = strlen(fix[i]->style) + 1; fwrite(&n,sizeof(int),1,fp); fwrite(fix[i]->style,sizeof(char),n,fp); fwrite(&maxsize_restart,sizeof(int),1,fp); } } } /* ---------------------------------------------------------------------- read in restart file data on all previously defined Fixes with restart info (1) fixes that have global state (2) fixes that store per-atom quantities return maxsize of extra info that will be stored with any atom ------------------------------------------------------------------------- */ int Modify::read_restart(FILE *fp) { // nfix_restart_global = # of restart entries with global state info int me = comm->me; if (me == 0) fread(&nfix_restart_global,sizeof(int),1,fp); MPI_Bcast(&nfix_restart_global,1,MPI_INT,0,world); // allocate space for each entry if (nfix_restart_global) { id_restart_global = new char*[nfix_restart_global]; style_restart_global = new char*[nfix_restart_global]; state_restart_global = new char*[nfix_restart_global]; used_restart_global = new int[nfix_restart_global]; } // read each entry and Bcast to all procs // each entry has id string, style string, chunk of state data int n; for (int i = 0; i < nfix_restart_global; i++) { if (me == 0) fread(&n,sizeof(int),1,fp); MPI_Bcast(&n,1,MPI_INT,0,world); id_restart_global[i] = new char[n]; if (me == 0) fread(id_restart_global[i],sizeof(char),n,fp); MPI_Bcast(id_restart_global[i],n,MPI_CHAR,0,world); if (me == 0) fread(&n,sizeof(int),1,fp); MPI_Bcast(&n,1,MPI_INT,0,world); style_restart_global[i] = new char[n]; if (me == 0) fread(style_restart_global[i],sizeof(char),n,fp); MPI_Bcast(style_restart_global[i],n,MPI_CHAR,0,world); if (me == 0) fread(&n,sizeof(int),1,fp); MPI_Bcast(&n,1,MPI_INT,0,world); state_restart_global[i] = new char[n]; if (me == 0) fread(state_restart_global[i],sizeof(char),n,fp); MPI_Bcast(state_restart_global[i],n,MPI_CHAR,0,world); used_restart_global[i] = 0; } // nfix_restart_peratom = # of restart entries with peratom info int maxsize = 0; if (me == 0) fread(&nfix_restart_peratom,sizeof(int),1,fp); MPI_Bcast(&nfix_restart_peratom,1,MPI_INT,0,world); // allocate space for each entry if (nfix_restart_peratom) { id_restart_peratom = new char*[nfix_restart_peratom]; style_restart_peratom = new char*[nfix_restart_peratom]; index_restart_peratom = new int[nfix_restart_peratom]; used_restart_peratom = new int[nfix_restart_peratom]; } // read each entry and Bcast to all procs // each entry has id string, style string, maxsize of one atom's data // set index = which set of extra data this fix represents for (int i = 0; i < nfix_restart_peratom; i++) { if (me == 0) fread(&n,sizeof(int),1,fp); MPI_Bcast(&n,1,MPI_INT,0,world); id_restart_peratom[i] = new char[n]; if (me == 0) fread(id_restart_peratom[i],sizeof(char),n,fp); MPI_Bcast(id_restart_peratom[i],n,MPI_CHAR,0,world); if (me == 0) fread(&n,sizeof(int),1,fp); MPI_Bcast(&n,1,MPI_INT,0,world); style_restart_peratom[i] = new char[n]; if (me == 0) fread(style_restart_peratom[i],sizeof(char),n,fp); MPI_Bcast(style_restart_peratom[i],n,MPI_CHAR,0,world); if (me == 0) fread(&n,sizeof(int),1,fp); MPI_Bcast(&n,1,MPI_INT,0,world); maxsize += n; index_restart_peratom[i] = i; used_restart_peratom[i] = 0; } return maxsize; } /* ---------------------------------------------------------------------- delete all lists of restart file Fix info if flag set, print list of restart file info not assigned to new fixes ------------------------------------------------------------------------- */ void Modify::restart_deallocate(int flag) { if (nfix_restart_global) { if (flag && comm->me == 0) { int i; for (i = 0; i < nfix_restart_global; i++) if (used_restart_global[i] == 0) break; if (i == nfix_restart_global) { if (screen) fprintf(screen,"All restart file global fix info " "was re-assigned\n"); if (logfile) fprintf(logfile,"All restart file global fix info " "was re-assigned\n"); } else { if (screen) fprintf(screen,"Unused restart file global fix info:\n"); if (logfile) fprintf(logfile,"Unused restart file global fix info:\n"); for (i = 0; i < nfix_restart_global; i++) { if (used_restart_global[i]) continue; if (screen) fprintf(screen," fix style: %s, fix ID: %s\n", style_restart_global[i],id_restart_global[i]); if (logfile) fprintf(logfile," fix style: %s, fix ID: %s\n", style_restart_global[i],id_restart_global[i]); } } } for (int i = 0; i < nfix_restart_global; i++) { delete [] id_restart_global[i]; delete [] style_restart_global[i]; delete [] state_restart_global[i]; } delete [] id_restart_global; delete [] style_restart_global; delete [] state_restart_global; delete [] used_restart_global; } if (nfix_restart_peratom) { if (flag && comm->me == 0) { int i; for (i = 0; i < nfix_restart_peratom; i++) if (used_restart_peratom[i] == 0) break; if (i == nfix_restart_peratom) { if (screen) fprintf(screen,"All restart file peratom fix info " "was re-assigned\n"); if (logfile) fprintf(logfile,"All restart file peratom fix info " "was re-assigned\n"); } else { if (screen) fprintf(screen,"Unused restart file peratom fix info:\n"); if (logfile) fprintf(logfile,"Unused restart file peratom fix info:\n"); for (i = 0; i < nfix_restart_peratom; i++) { if (used_restart_peratom[i]) continue; if (screen) fprintf(screen," fix style: %s, fix ID: %s\n", style_restart_peratom[i],id_restart_peratom[i]); if (logfile) fprintf(logfile," fix style: %s, fix ID: %s\n", style_restart_peratom[i],id_restart_peratom[i]); } } } for (int i = 0; i < nfix_restart_peratom; i++) { delete [] id_restart_peratom[i]; delete [] style_restart_peratom[i]; } delete [] id_restart_peratom; delete [] style_restart_peratom; delete [] index_restart_peratom; delete [] used_restart_peratom; } nfix_restart_global = nfix_restart_peratom = 0; } /* ---------------------------------------------------------------------- create list of fix indices for fixes which match mask ------------------------------------------------------------------------- */ void Modify::list_init(int mask, int &n, int *&list) { delete [] list; n = 0; for (int i = 0; i < nfix; i++) if (fmask[i] & mask) n++; list = new int[n]; n = 0; for (int i = 0; i < nfix; i++) if (fmask[i] & mask) list[n++] = i; } /* ---------------------------------------------------------------------- create list of fix indices for end_of_step fixes also create end_of_step_every[] ------------------------------------------------------------------------- */ void Modify::list_init_end_of_step(int mask, int &n, int *&list) { delete [] list; delete [] end_of_step_every; n = 0; for (int i = 0; i < nfix; i++) if (fmask[i] & mask) n++; list = new int[n]; end_of_step_every = new int[n]; n = 0; for (int i = 0; i < nfix; i++) if (fmask[i] & mask) { list[n] = i; end_of_step_every[n++] = fix[i]->nevery; } } /* ---------------------------------------------------------------------- create list of fix indices for thermo energy fixes only added to list if fix has THERMO_ENERGY mask set, and its thermo_energy flag was set via fix_modify ------------------------------------------------------------------------- */ void Modify::list_init_thermo_energy(int mask, int &n, int *&list) { delete [] list; n = 0; for (int i = 0; i < nfix; i++) if (fmask[i] & mask && fix[i]->thermo_energy) n++; list = new int[n]; n = 0; for (int i = 0; i < nfix; i++) if (fmask[i] & mask && fix[i]->thermo_energy) list[n++] = i; } /* ---------------------------------------------------------------------- create list of fix indices for peratom thermo energy fixes only added to list if fix has its peatom_flag set, and its thermo_energy flag was set via fix_modify ------------------------------------------------------------------------- */ void Modify::list_init_thermo_energy_atom(int &n, int *&list) { delete [] list; n = 0; for (int i = 0; i < nfix; i++) if (fix[i]->peatom_flag && fix[i]->thermo_energy) n++; list = new int[n]; n = 0; for (int i = 0; i < nfix; i++) if (fix[i]->peatom_flag && fix[i]->thermo_energy) list[n++] = i; } /* ---------------------------------------------------------------------- create list of compute indices for computes which store invocation times ------------------------------------------------------------------------- */ void Modify::list_init_compute() { delete [] list_timeflag; n_timeflag = 0; for (int i = 0; i < ncompute; i++) if (compute[i]->timeflag) n_timeflag++; list_timeflag = new int[n_timeflag]; n_timeflag = 0; for (int i = 0; i < ncompute; i++) if (compute[i]->timeflag) list_timeflag[n_timeflag++] = i; } /* ---------------------------------------------------------------------- return # of bytes of allocated memory from all fixes ------------------------------------------------------------------------- */ bigint Modify::memory_usage() { bigint bytes = 0; for (int i = 0; i < nfix; i++) bytes += static_cast (fix[i]->memory_usage()); for (int i = 0; i < ncompute; i++) bytes += static_cast (compute[i]->memory_usage()); return bytes; }